goscript 0.1.0 → 0.1.2

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 (495) hide show
  1. package/README.md +267 -255
  2. package/cmd/goscript/cmd-test.go +286 -0
  3. package/cmd/goscript/cmd-test_test.go +76 -0
  4. package/cmd/goscript/cmd_compile.go +9 -0
  5. package/cmd/goscript/main.go +1 -0
  6. package/compiler/build-flags.go +38 -0
  7. package/compiler/compile-request.go +33 -0
  8. package/compiler/compiler.go +1 -1
  9. package/compiler/compliance_test.go +0 -10
  10. package/compiler/config.go +2 -0
  11. package/compiler/gotest/owner.go +24 -0
  12. package/compiler/gotest/package-result.go +69 -0
  13. package/compiler/gotest/request.go +210 -0
  14. package/compiler/gotest/result.go +28 -0
  15. package/compiler/gotest/runner.go +1225 -0
  16. package/compiler/gotest/runner_test.go +1271 -0
  17. package/compiler/gotest/test.go +9 -0
  18. package/compiler/index.test.ts +1 -1
  19. package/compiler/lowered-program.go +80 -21
  20. package/compiler/lowering.go +6754 -602
  21. package/compiler/override-facts.go +357 -0
  22. package/compiler/override-registry.go +52 -190
  23. package/compiler/override-registry_test.go +182 -0
  24. package/compiler/package-graph.go +50 -27
  25. package/compiler/package-graph_test.go +99 -9
  26. package/compiler/package-test-function.go +9 -0
  27. package/compiler/package-test-graph-package.go +40 -0
  28. package/compiler/package-test-graph-variant.go +129 -0
  29. package/compiler/package-test-graph.go +112 -0
  30. package/compiler/package-test-graph_test.go +202 -0
  31. package/compiler/runtime-contract.go +229 -29
  32. package/compiler/runtime-contract_test.go +44 -30
  33. package/compiler/semantic-model-types.go +25 -6
  34. package/compiler/semantic-model.go +819 -74
  35. package/compiler/semantic-model_test.go +104 -0
  36. package/compiler/service.go +10 -4
  37. package/compiler/skeleton_test.go +2777 -524
  38. package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
  39. package/compiler/tsworkspace/owner.go +342 -0
  40. package/compiler/tsworkspace/owner_test.go +93 -0
  41. package/compiler/tsworkspace/result.go +17 -0
  42. package/compiler/tsworkspace/tool-process-other.go +14 -0
  43. package/compiler/tsworkspace/tool-process-unix.go +19 -0
  44. package/compiler/typescript-emitter.go +576 -86
  45. package/compiler/wasm/compile.go +1 -1
  46. package/compiler/wasm/compile_test.go +61 -11
  47. package/compiler/wasm_api.go +172 -7
  48. package/dist/gs/builtin/builtin.d.ts +40 -3
  49. package/dist/gs/builtin/builtin.js +430 -22
  50. package/dist/gs/builtin/builtin.js.map +1 -1
  51. package/dist/gs/builtin/channel.d.ts +32 -10
  52. package/dist/gs/builtin/channel.js +119 -25
  53. package/dist/gs/builtin/channel.js.map +1 -1
  54. package/dist/gs/builtin/defer.d.ts +1 -0
  55. package/dist/gs/builtin/defer.js +12 -2
  56. package/dist/gs/builtin/defer.js.map +1 -1
  57. package/dist/gs/builtin/hostio.d.ts +9 -0
  58. package/dist/gs/builtin/hostio.js +25 -0
  59. package/dist/gs/builtin/hostio.js.map +1 -1
  60. package/dist/gs/builtin/map.js +40 -6
  61. package/dist/gs/builtin/map.js.map +1 -1
  62. package/dist/gs/builtin/print.js.map +1 -1
  63. package/dist/gs/builtin/slice.d.ts +64 -10
  64. package/dist/gs/builtin/slice.js +619 -244
  65. package/dist/gs/builtin/slice.js.map +1 -1
  66. package/dist/gs/builtin/type.d.ts +7 -2
  67. package/dist/gs/builtin/type.js +128 -29
  68. package/dist/gs/builtin/type.js.map +1 -1
  69. package/dist/gs/builtin/varRef.d.ts +7 -0
  70. package/dist/gs/builtin/varRef.js +23 -0
  71. package/dist/gs/builtin/varRef.js.map +1 -1
  72. package/dist/gs/bytes/buffer.gs.js +74 -70
  73. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  74. package/dist/gs/bytes/iter.gs.js +13 -13
  75. package/dist/gs/bytes/iter.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/compress/zlib/index.d.ts +26 -0
  79. package/dist/gs/compress/zlib/index.js +168 -0
  80. package/dist/gs/compress/zlib/index.js.map +1 -0
  81. package/dist/gs/context/context.d.ts +6 -5
  82. package/dist/gs/context/context.js +17 -12
  83. package/dist/gs/context/context.js.map +1 -1
  84. package/dist/gs/crypto/ecdh/index.d.ts +52 -0
  85. package/dist/gs/crypto/ecdh/index.js +226 -0
  86. package/dist/gs/crypto/ecdh/index.js.map +1 -0
  87. package/dist/gs/crypto/ed25519/index.d.ts +34 -0
  88. package/dist/gs/crypto/ed25519/index.js +160 -0
  89. package/dist/gs/crypto/ed25519/index.js.map +1 -0
  90. package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
  91. package/dist/gs/crypto/internal/constanttime/index.js +18 -0
  92. package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
  93. package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
  94. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
  95. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
  96. package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
  97. package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
  98. package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
  99. package/dist/gs/crypto/rand/index.d.ts +2 -0
  100. package/dist/gs/crypto/rand/index.js +85 -0
  101. package/dist/gs/crypto/rand/index.js.map +1 -1
  102. package/dist/gs/crypto/sha256/index.d.ts +8 -0
  103. package/dist/gs/crypto/sha256/index.js +118 -0
  104. package/dist/gs/crypto/sha256/index.js.map +1 -0
  105. package/dist/gs/crypto/sha512/index.d.ts +14 -0
  106. package/dist/gs/crypto/sha512/index.js +129 -0
  107. package/dist/gs/crypto/sha512/index.js.map +1 -0
  108. package/dist/gs/embed/index.d.ts +7 -0
  109. package/dist/gs/embed/index.js +16 -0
  110. package/dist/gs/embed/index.js.map +1 -0
  111. package/dist/gs/encoding/json/index.d.ts +4 -0
  112. package/dist/gs/encoding/json/index.js +33 -0
  113. package/dist/gs/encoding/json/index.js.map +1 -1
  114. package/dist/gs/errors/errors.d.ts +4 -0
  115. package/dist/gs/errors/errors.js +108 -4
  116. package/dist/gs/errors/errors.js.map +1 -1
  117. package/dist/gs/fmt/fmt.d.ts +4 -4
  118. package/dist/gs/fmt/fmt.js +42 -11
  119. package/dist/gs/fmt/fmt.js.map +1 -1
  120. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +37 -2
  121. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +245 -1
  122. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  123. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
  124. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +861 -0
  125. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
  126. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +217 -0
  127. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +814 -0
  128. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
  129. package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
  130. package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
  131. package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
  132. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  133. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
  134. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
  135. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
  136. package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
  137. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +72 -0
  138. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
  139. package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
  140. package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
  141. package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
  142. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
  143. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
  144. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
  145. package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
  146. package/dist/gs/go/internal/scannerhooks/index.js +5 -0
  147. package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
  148. package/dist/gs/go/scanner/index.d.ts +13 -0
  149. package/dist/gs/go/scanner/index.js +35 -0
  150. package/dist/gs/go/scanner/index.js.map +1 -1
  151. package/dist/gs/go/token/index.d.ts +156 -0
  152. package/dist/gs/go/token/index.js +507 -4
  153. package/dist/gs/go/token/index.js.map +1 -1
  154. package/dist/gs/hash/fnv/index.d.ts +57 -0
  155. package/dist/gs/hash/fnv/index.js +299 -0
  156. package/dist/gs/hash/fnv/index.js.map +1 -0
  157. package/dist/gs/hash/index.d.ts +17 -0
  158. package/dist/gs/hash/index.js +94 -0
  159. package/dist/gs/hash/index.js.map +1 -0
  160. package/dist/gs/internal/abi/index.d.ts +4 -0
  161. package/dist/gs/internal/abi/index.js +10 -0
  162. package/dist/gs/internal/abi/index.js.map +1 -1
  163. package/dist/gs/internal/bytealg/index.d.ts +2 -0
  164. package/dist/gs/internal/bytealg/index.js +14 -0
  165. package/dist/gs/internal/bytealg/index.js.map +1 -1
  166. package/dist/gs/internal/byteorder/index.d.ts +8 -2
  167. package/dist/gs/internal/byteorder/index.js +56 -25
  168. package/dist/gs/internal/byteorder/index.js.map +1 -1
  169. package/dist/gs/internal/godebug/index.d.ts +12 -0
  170. package/dist/gs/internal/godebug/index.js +30 -0
  171. package/dist/gs/internal/godebug/index.js.map +1 -0
  172. package/dist/gs/io/fs/index.d.ts +1 -0
  173. package/dist/gs/io/fs/index.js +1 -0
  174. package/dist/gs/io/fs/index.js.map +1 -1
  175. package/dist/gs/io/fs/readlink.d.ts +8 -0
  176. package/dist/gs/io/fs/readlink.js +60 -0
  177. package/dist/gs/io/fs/readlink.js.map +1 -0
  178. package/dist/gs/io/fs/walk.d.ts +3 -3
  179. package/dist/gs/io/fs/walk.js +7 -7
  180. package/dist/gs/io/fs/walk.js.map +1 -1
  181. package/dist/gs/io/io.d.ts +40 -6
  182. package/dist/gs/io/io.js +151 -26
  183. package/dist/gs/io/io.js.map +1 -1
  184. package/dist/gs/iter/iter.d.ts +3 -2
  185. package/dist/gs/iter/iter.js.map +1 -1
  186. package/dist/gs/maps/iter.d.ts +5 -5
  187. package/dist/gs/maps/iter.js +48 -21
  188. package/dist/gs/maps/iter.js.map +1 -1
  189. package/dist/gs/maps/maps.d.ts +6 -6
  190. package/dist/gs/maps/maps.js +1 -1
  191. package/dist/gs/maps/maps.js.map +1 -1
  192. package/dist/gs/math/bits/index.d.ts +13 -4
  193. package/dist/gs/math/bits/index.js +70 -48
  194. package/dist/gs/math/bits/index.js.map +1 -1
  195. package/dist/gs/math/const.gs.d.ts +5 -5
  196. package/dist/gs/math/const.gs.js +4 -4
  197. package/dist/gs/math/const.gs.js.map +1 -1
  198. package/dist/gs/mime/index.d.ts +1 -0
  199. package/dist/gs/mime/index.js +52 -0
  200. package/dist/gs/mime/index.js.map +1 -0
  201. package/dist/gs/net/http/httptest/index.d.ts +30 -0
  202. package/dist/gs/net/http/httptest/index.js +101 -0
  203. package/dist/gs/net/http/httptest/index.js.map +1 -0
  204. package/dist/gs/net/http/index.d.ts +131 -0
  205. package/dist/gs/net/http/index.js +307 -0
  206. package/dist/gs/net/http/index.js.map +1 -0
  207. package/dist/gs/net/http/pprof/index.d.ts +8 -0
  208. package/dist/gs/net/http/pprof/index.js +59 -0
  209. package/dist/gs/net/http/pprof/index.js.map +1 -0
  210. package/dist/gs/os/dir_unix.gs.js +2 -2
  211. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  212. package/dist/gs/os/error.gs.js +9 -7
  213. package/dist/gs/os/error.gs.js.map +1 -1
  214. package/dist/gs/os/types_js.gs.js +95 -15
  215. package/dist/gs/os/types_js.gs.js.map +1 -1
  216. package/dist/gs/path/filepath/match.js +165 -3
  217. package/dist/gs/path/filepath/match.js.map +1 -1
  218. package/dist/gs/path/filepath/path.d.ts +8 -4
  219. package/dist/gs/path/filepath/path.js +192 -8
  220. package/dist/gs/path/filepath/path.js.map +1 -1
  221. package/dist/gs/path/path.d.ts +4 -1
  222. package/dist/gs/path/path.js +16 -4
  223. package/dist/gs/path/path.js.map +1 -1
  224. package/dist/gs/reflect/index.d.ts +4 -3
  225. package/dist/gs/reflect/index.js +3 -2
  226. package/dist/gs/reflect/index.js.map +1 -1
  227. package/dist/gs/reflect/iter.js +2 -2
  228. package/dist/gs/reflect/iter.js.map +1 -1
  229. package/dist/gs/reflect/map.js +29 -0
  230. package/dist/gs/reflect/map.js.map +1 -1
  231. package/dist/gs/reflect/type.d.ts +31 -9
  232. package/dist/gs/reflect/type.js +536 -43
  233. package/dist/gs/reflect/type.js.map +1 -1
  234. package/dist/gs/reflect/types.d.ts +1 -0
  235. package/dist/gs/reflect/types.js +3 -1
  236. package/dist/gs/reflect/types.js.map +1 -1
  237. package/dist/gs/reflect/value.d.ts +4 -1
  238. package/dist/gs/reflect/value.js +39 -1
  239. package/dist/gs/reflect/value.js.map +1 -1
  240. package/dist/gs/reflect/visiblefields.js +1 -1
  241. package/dist/gs/reflect/visiblefields.js.map +1 -1
  242. package/dist/gs/runtime/debug/index.d.ts +41 -0
  243. package/dist/gs/runtime/debug/index.js +66 -0
  244. package/dist/gs/runtime/debug/index.js.map +1 -0
  245. package/dist/gs/runtime/pprof/index.d.ts +20 -0
  246. package/dist/gs/runtime/pprof/index.js +85 -0
  247. package/dist/gs/runtime/pprof/index.js.map +1 -0
  248. package/dist/gs/runtime/runtime.d.ts +35 -3
  249. package/dist/gs/runtime/runtime.js +72 -0
  250. package/dist/gs/runtime/runtime.js.map +1 -1
  251. package/dist/gs/runtime/trace/index.d.ts +19 -0
  252. package/dist/gs/runtime/trace/index.js +64 -0
  253. package/dist/gs/runtime/trace/index.js.map +1 -0
  254. package/dist/gs/slices/slices.d.ts +42 -8
  255. package/dist/gs/slices/slices.js +425 -11
  256. package/dist/gs/slices/slices.js.map +1 -1
  257. package/dist/gs/sort/slice.gs.d.ts +5 -3
  258. package/dist/gs/sort/slice.gs.js +60 -22
  259. package/dist/gs/sort/slice.gs.js.map +1 -1
  260. package/dist/gs/sort/sort.gs.d.ts +4 -4
  261. package/dist/gs/sort/sort.gs.js +11 -8
  262. package/dist/gs/sort/sort.gs.js.map +1 -1
  263. package/dist/gs/strings/builder.d.ts +1 -1
  264. package/dist/gs/strings/builder.js +29 -19
  265. package/dist/gs/strings/builder.js.map +1 -1
  266. package/dist/gs/strings/iter.js +140 -75
  267. package/dist/gs/strings/iter.js.map +1 -1
  268. package/dist/gs/strings/replace.js +2 -2
  269. package/dist/gs/strings/replace.js.map +1 -1
  270. package/dist/gs/strings/strings.js +52 -6
  271. package/dist/gs/strings/strings.js.map +1 -1
  272. package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
  273. package/dist/gs/sync/atomic/type.gs.js +0 -2
  274. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  275. package/dist/gs/sync/sync.d.ts +8 -3
  276. package/dist/gs/sync/sync.js +66 -11
  277. package/dist/gs/sync/sync.js.map +1 -1
  278. package/dist/gs/syscall/constants.d.ts +36 -24
  279. package/dist/gs/syscall/constants.js +12 -0
  280. package/dist/gs/syscall/constants.js.map +1 -1
  281. package/dist/gs/syscall/errors.d.ts +117 -111
  282. package/dist/gs/syscall/errors.js +45 -0
  283. package/dist/gs/syscall/errors.js.map +1 -1
  284. package/dist/gs/syscall/fs.d.ts +37 -0
  285. package/dist/gs/syscall/fs.js +102 -0
  286. package/dist/gs/syscall/fs.js.map +1 -1
  287. package/dist/gs/syscall/js/index.d.ts +90 -0
  288. package/dist/gs/syscall/js/index.js +383 -0
  289. package/dist/gs/syscall/js/index.js.map +1 -0
  290. package/dist/gs/syscall/types.d.ts +26 -1
  291. package/dist/gs/syscall/types.js +45 -1
  292. package/dist/gs/syscall/types.js.map +1 -1
  293. package/dist/gs/testing/index.d.ts +1 -0
  294. package/dist/gs/testing/index.js +2 -0
  295. package/dist/gs/testing/index.js.map +1 -0
  296. package/dist/gs/testing/testing.d.ts +78 -0
  297. package/dist/gs/testing/testing.js +318 -0
  298. package/dist/gs/testing/testing.js.map +1 -0
  299. package/dist/gs/time/time.d.ts +41 -4
  300. package/dist/gs/time/time.js +227 -36
  301. package/dist/gs/time/time.js.map +1 -1
  302. package/dist/gs/unicode/unicode.d.ts +23 -1
  303. package/dist/gs/unicode/unicode.js +79 -10
  304. package/dist/gs/unicode/unicode.js.map +1 -1
  305. package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
  306. package/dist/gs/unicode/utf8/utf8.js +24 -11
  307. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  308. package/dist/gs/unique/index.d.ts +11 -0
  309. package/dist/gs/unique/index.js +76 -0
  310. package/dist/gs/unique/index.js.map +1 -0
  311. package/go.mod +8 -8
  312. package/go.sum +14 -14
  313. package/gs/builtin/builtin.ts +585 -27
  314. package/gs/builtin/channel.ts +183 -29
  315. package/gs/builtin/defer.ts +13 -2
  316. package/gs/builtin/hostio.test.ts +1 -0
  317. package/gs/builtin/hostio.ts +38 -0
  318. package/gs/builtin/map.ts +46 -6
  319. package/gs/builtin/print.ts +12 -3
  320. package/gs/builtin/runtime-contract.test.ts +383 -10
  321. package/gs/builtin/slice.test.ts +70 -0
  322. package/gs/builtin/slice.ts +785 -265
  323. package/gs/builtin/type.ts +160 -41
  324. package/gs/builtin/varRef.ts +40 -1
  325. package/gs/bytes/buffer.gs.ts +74 -70
  326. package/gs/bytes/iter.gs.ts +13 -14
  327. package/gs/bytes/meta.json +8 -3
  328. package/gs/bytes/reader.gs.ts +20 -19
  329. package/gs/compress/zlib/index.test.ts +28 -0
  330. package/gs/compress/zlib/index.ts +200 -0
  331. package/gs/compress/zlib/meta.json +3 -0
  332. package/gs/context/context.test.ts +71 -0
  333. package/gs/context/context.ts +30 -29
  334. package/gs/crypto/ecdh/index.test.ts +43 -0
  335. package/gs/crypto/ecdh/index.ts +274 -0
  336. package/gs/crypto/ed25519/index.test.ts +41 -0
  337. package/gs/crypto/ed25519/index.ts +238 -0
  338. package/gs/crypto/ed25519/meta.json +13 -0
  339. package/gs/crypto/internal/constanttime/index.test.ts +25 -0
  340. package/gs/crypto/internal/constanttime/index.ts +22 -0
  341. package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
  342. package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
  343. package/gs/crypto/rand/index.test.ts +89 -1
  344. package/gs/crypto/rand/index.ts +103 -1
  345. package/gs/crypto/rand/meta.json +4 -1
  346. package/gs/crypto/sha256/index.test.ts +78 -0
  347. package/gs/crypto/sha256/index.ts +150 -0
  348. package/gs/crypto/sha256/meta.json +9 -0
  349. package/gs/crypto/sha512/index.test.ts +31 -0
  350. package/gs/crypto/sha512/index.ts +161 -0
  351. package/gs/crypto/sha512/meta.json +11 -0
  352. package/gs/embed/index.ts +20 -0
  353. package/gs/embed/meta.json +5 -0
  354. package/gs/encoding/json/index.test.ts +39 -3
  355. package/gs/encoding/json/index.ts +45 -3
  356. package/gs/errors/errors.test.ts +85 -0
  357. package/gs/errors/errors.ts +132 -4
  358. package/gs/fmt/fmt.test.ts +3 -1
  359. package/gs/fmt/fmt.ts +55 -19
  360. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +128 -1
  361. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +342 -4
  362. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +180 -0
  363. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1084 -0
  364. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
  365. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +1233 -0
  366. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +46 -0
  367. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
  368. package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
  369. package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
  370. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
  371. package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
  372. package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
  373. package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
  374. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +37 -0
  375. package/gs/github.com/klauspost/compress/internal/le/index.ts +115 -0
  376. package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
  377. package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
  378. package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
  379. package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
  380. package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
  381. package/gs/go/internal/scannerhooks/index.test.ts +14 -0
  382. package/gs/go/internal/scannerhooks/index.ts +9 -0
  383. package/gs/go/scanner/index.test.ts +22 -0
  384. package/gs/go/scanner/index.ts +47 -0
  385. package/gs/go/token/index.test.ts +47 -1
  386. package/gs/go/token/index.ts +583 -4
  387. package/gs/hash/fnv/index.test.ts +67 -0
  388. package/gs/hash/fnv/index.ts +351 -0
  389. package/gs/hash/fnv/meta.json +3 -0
  390. package/gs/hash/index.test.ts +37 -0
  391. package/gs/hash/index.ts +118 -0
  392. package/gs/hash/meta.json +5 -0
  393. package/gs/internal/abi/index.test.ts +18 -0
  394. package/gs/internal/abi/index.ts +14 -0
  395. package/gs/internal/bytealg/index.test.ts +18 -0
  396. package/gs/internal/bytealg/index.ts +16 -0
  397. package/gs/internal/byteorder/index.test.ts +39 -0
  398. package/gs/internal/byteorder/index.ts +100 -27
  399. package/gs/internal/godebug/index.test.ts +16 -0
  400. package/gs/internal/godebug/index.ts +35 -0
  401. package/gs/io/fs/index.ts +1 -0
  402. package/gs/io/fs/meta.json +5 -0
  403. package/gs/io/fs/readlink.test.ts +43 -0
  404. package/gs/io/fs/readlink.ts +69 -0
  405. package/gs/io/fs/walk.test.ts +61 -0
  406. package/gs/io/fs/walk.ts +17 -9
  407. package/gs/io/io.ts +177 -31
  408. package/gs/io/meta.json +10 -2
  409. package/gs/iter/iter.ts +8 -2
  410. package/gs/maps/iter.ts +75 -26
  411. package/gs/maps/maps.test.ts +23 -0
  412. package/gs/maps/maps.ts +13 -11
  413. package/gs/math/bits/index.test.ts +20 -0
  414. package/gs/math/bits/index.ts +107 -64
  415. package/gs/math/const.gs.test.ts +11 -5
  416. package/gs/math/const.gs.ts +5 -6
  417. package/gs/mime/index.ts +60 -0
  418. package/gs/net/http/httptest/index.test.ts +53 -0
  419. package/gs/net/http/httptest/index.ts +120 -0
  420. package/gs/net/http/index.test.ts +148 -0
  421. package/gs/net/http/index.ts +432 -0
  422. package/gs/net/http/meta.json +6 -0
  423. package/gs/net/http/pprof/index.test.ts +47 -0
  424. package/gs/net/http/pprof/index.ts +65 -0
  425. package/gs/os/dir_unix.gs.ts +2 -3
  426. package/gs/os/error.gs.ts +9 -10
  427. package/gs/os/error.test.ts +41 -0
  428. package/gs/os/file_unix_js.test.ts +55 -0
  429. package/gs/os/tempfile.gs.test.ts +37 -10
  430. package/gs/os/types_js.gs.ts +96 -17
  431. package/gs/path/filepath/match.test.ts +31 -12
  432. package/gs/path/filepath/match.ts +181 -3
  433. package/gs/path/filepath/meta.json +6 -0
  434. package/gs/path/filepath/path.test.ts +80 -0
  435. package/gs/path/filepath/path.ts +244 -11
  436. package/gs/path/path.ts +20 -5
  437. package/gs/reflect/field.test.ts +63 -0
  438. package/gs/reflect/index.ts +5 -1
  439. package/gs/reflect/iter.ts +2 -2
  440. package/gs/reflect/map.test.ts +42 -1
  441. package/gs/reflect/map.ts +39 -0
  442. package/gs/reflect/type.ts +728 -65
  443. package/gs/reflect/typefor.test.ts +100 -0
  444. package/gs/reflect/types.ts +3 -1
  445. package/gs/reflect/value.ts +50 -1
  446. package/gs/reflect/visiblefields.ts +1 -1
  447. package/gs/runtime/debug/index.test.ts +45 -0
  448. package/gs/runtime/debug/index.ts +96 -0
  449. package/gs/runtime/pprof/index.test.ts +36 -0
  450. package/gs/runtime/pprof/index.ts +104 -0
  451. package/gs/runtime/pprof/meta.json +6 -0
  452. package/gs/runtime/runtime.test.ts +19 -0
  453. package/gs/runtime/runtime.ts +98 -3
  454. package/gs/runtime/trace/index.test.ts +45 -0
  455. package/gs/runtime/trace/index.ts +97 -0
  456. package/gs/runtime/trace/meta.json +7 -0
  457. package/gs/slices/meta.json +2 -1
  458. package/gs/slices/slices.test.ts +180 -0
  459. package/gs/slices/slices.ts +502 -15
  460. package/gs/sort/meta.json +7 -0
  461. package/gs/sort/slice.gs.ts +85 -26
  462. package/gs/sort/slice.test.ts +40 -0
  463. package/gs/sort/sort.gs.ts +16 -13
  464. package/gs/strings/builder.test.ts +8 -0
  465. package/gs/strings/builder.ts +33 -20
  466. package/gs/strings/iter.test.ts +5 -7
  467. package/gs/strings/iter.ts +146 -71
  468. package/gs/strings/replace.test.ts +1 -4
  469. package/gs/strings/replace.ts +6 -6
  470. package/gs/strings/strings.test.ts +4 -0
  471. package/gs/strings/strings.ts +54 -6
  472. package/gs/sync/atomic/type.gs.ts +13 -14
  473. package/gs/sync/meta.json +3 -1
  474. package/gs/sync/sync.test.ts +69 -1
  475. package/gs/sync/sync.ts +72 -13
  476. package/gs/syscall/constants.ts +39 -24
  477. package/gs/syscall/errors.ts +165 -112
  478. package/gs/syscall/fs.ts +195 -0
  479. package/gs/syscall/js/index.ts +485 -0
  480. package/gs/syscall/js/meta.json +4 -0
  481. package/gs/syscall/net.test.ts +111 -0
  482. package/gs/syscall/types.ts +63 -2
  483. package/gs/testing/index.ts +1 -0
  484. package/gs/testing/meta.json +5 -0
  485. package/gs/testing/testing.test.ts +146 -0
  486. package/gs/testing/testing.ts +399 -0
  487. package/gs/time/meta.json +2 -2
  488. package/gs/time/time.test.ts +110 -0
  489. package/gs/time/time.ts +309 -57
  490. package/gs/unicode/unicode.test.ts +36 -0
  491. package/gs/unicode/unicode.ts +115 -9
  492. package/gs/unicode/utf8/utf8.test.ts +13 -0
  493. package/gs/unicode/utf8/utf8.ts +28 -16
  494. package/gs/unique/index.ts +98 -0
  495. package/package.json +3 -2
@@ -6,6 +6,7 @@ import (
6
6
  "go/ast"
7
7
  "go/token"
8
8
  "go/types"
9
+ "maps"
9
10
  "slices"
10
11
  "strconv"
11
12
  "strings"
@@ -68,35 +69,66 @@ func (o *SemanticModelOwner) Build(ctx context.Context, graph *PackageGraph) (*S
68
69
  })
69
70
  continue
70
71
  }
71
- diagnostics = append(diagnostics, o.buildPackage(model, node, pkg)...)
72
+ diagnostics = append(diagnostics, o.buildPackage(ctx, model, node, pkg)...)
72
73
  }
73
74
  if diagnosticsHaveErrors(diagnostics) {
74
75
  return model, diagnostics
75
76
  }
76
77
 
77
- o.propagateFunctionAsync(model)
78
- o.resolveInterfaceImplementations(model)
79
- o.propagateFunctionAsync(model)
78
+ diagnostics = append(diagnostics, o.propagateFunctionAsync(ctx, model)...)
79
+ if diagnosticsHaveErrors(diagnostics) {
80
+ return model, diagnostics
81
+ }
82
+ diagnostics = append(diagnostics, o.propagateAsyncFunctionArguments(ctx, model)...)
83
+ if diagnosticsHaveErrors(diagnostics) {
84
+ return model, diagnostics
85
+ }
86
+ interfaceGraph, interfaceDiagnostics := o.resolveInterfaceImplementationGraph(ctx, model)
87
+ diagnostics = append(diagnostics, interfaceDiagnostics...)
88
+ if diagnosticsHaveErrors(diagnostics) {
89
+ return model, diagnostics
90
+ }
91
+ for {
92
+ asyncCount := semanticAsyncFunctionCount(model)
93
+ diagnostics = append(diagnostics, o.applyInterfaceAsyncMethods(ctx, model, interfaceGraph)...)
94
+ if diagnosticsHaveErrors(diagnostics) {
95
+ return model, diagnostics
96
+ }
97
+ diagnostics = append(diagnostics, o.propagateFunctionAsync(ctx, model)...)
98
+ if diagnosticsHaveErrors(diagnostics) {
99
+ return model, diagnostics
100
+ }
101
+ if semanticAsyncFunctionCount(model) == asyncCount {
102
+ break
103
+ }
104
+ }
80
105
  return model, diagnostics
81
106
  }
82
107
 
83
108
  func newSemanticModel() *SemanticModel {
84
109
  return &SemanticModel{
85
- packages: make(map[string]*semanticPackage),
86
- addressTaken: make(map[types.Object]bool),
87
- needsVarRef: make(map[types.Object]bool),
88
- functions: make(map[*types.Func]*semanticFunction),
89
- types: make(map[*types.Named]*semanticType),
90
- values: make(map[types.Object]*semanticValue),
91
- generatedImports: make(map[string]map[string]bool),
110
+ packages: make(map[string]*semanticPackage),
111
+ addressTaken: make(map[types.Object]bool),
112
+ needsVarRef: make(map[types.Object]bool),
113
+ functions: make(map[*types.Func]*semanticFunction),
114
+ functionsByFullName: make(map[string]*semanticFunction),
115
+ functionLookupMisses: make(map[*types.Func]bool),
116
+ types: make(map[*types.Named]*semanticType),
117
+ values: make(map[types.Object]*semanticValue),
118
+ generatedImports: make(map[string]map[string]bool),
92
119
  }
93
120
  }
94
121
 
95
122
  func (o *SemanticModelOwner) buildPackage(
123
+ ctx context.Context,
96
124
  model *SemanticModel,
97
125
  node *PackageGraphNode,
98
126
  pkg *packages.Package,
99
127
  ) []Diagnostic {
128
+ overrideFacts, diagnostics := o.overrideOwner.Facts(ctx)
129
+ if diagnosticsHaveErrors(diagnostics) {
130
+ return diagnostics
131
+ }
100
132
  semPkg := &semanticPackage{
101
133
  pkgPath: node.PkgPath,
102
134
  name: node.Name,
@@ -109,9 +141,8 @@ func (o *SemanticModelOwner) buildPackage(
109
141
  o.collectFileDeclarations(model, semPkg, pkg, file)
110
142
  o.collectFileFacts(model, semPkg, pkg, file)
111
143
  }
112
- var diagnostics []Diagnostic
113
144
  for _, file := range pkg.Syntax {
114
- diagnostics = append(diagnostics, o.collectFunctionFacts(model, pkg, file)...)
145
+ diagnostics = append(diagnostics, o.collectFunctionFacts(model, pkg, file, overrideFacts)...)
115
146
  }
116
147
  return diagnostics
117
148
  }
@@ -150,7 +181,8 @@ func (o *SemanticModelOwner) collectFileDeclarations(
150
181
  continue
151
182
  }
152
183
  position := sourcePos(pkg, typed.Name.Pos())
153
- o.addFunction(model, semPkg, fn, position)
184
+ semFn := o.addFunction(model, semPkg, fn, position)
185
+ semFn.hasBody = typed.Body != nil
154
186
  semPkg.declarations = append(semPkg.declarations, semanticDeclaration{
155
187
  kind: "func",
156
188
  name: typed.Name.Name,
@@ -176,6 +208,7 @@ func (o *SemanticModelOwner) collectGenDecl(
176
208
  }
177
209
  position := sourcePos(pkg, typed.Name.Pos())
178
210
  o.addType(model, semPkg, obj, position, typed.Type)
211
+ o.recordGeneratedImports(model, semPkg, position.file, pkg.PkgPath, obj.Type())
179
212
  semPkg.declarations = append(semPkg.declarations, semanticDeclaration{
180
213
  kind: "type",
181
214
  name: typed.Name.Name,
@@ -221,6 +254,51 @@ func (o *SemanticModelOwner) collectFileFacts(
221
254
  ) {
222
255
  ast.Inspect(file, func(node ast.Node) bool {
223
256
  switch typed := node.(type) {
257
+ case *ast.TypeSpec:
258
+ o.recordTypeSpec(model, semPkg, pkg, typed)
259
+ case *ast.Ident:
260
+ o.addDefinedObject(model, semPkg, pkg, typed)
261
+ case *ast.UnaryExpr:
262
+ if typed.Op == token.AND {
263
+ o.recordAddressTaken(model, pkg, typed.X)
264
+ }
265
+ case *ast.SelectorExpr:
266
+ o.recordPointerReceiverUse(model, pkg, typed)
267
+ case *ast.TypeAssertExpr:
268
+ o.recordTypeAssertion(semPkg, pkg, typed)
269
+ case *ast.ValueSpec:
270
+ o.recordValueSpecNilFacts(semPkg, pkg, typed)
271
+ names := make([]ast.Expr, 0, len(typed.Names))
272
+ for _, name := range typed.Names {
273
+ names = append(names, name)
274
+ }
275
+ o.recordAsyncCompatibleFunctionAssignments(model, pkg, names, typed.Values)
276
+ case *ast.AssignStmt:
277
+ o.recordAssignNilFacts(semPkg, pkg, typed)
278
+ o.recordAsyncCompatibleFunctionAssignments(model, pkg, typed.Lhs, typed.Rhs)
279
+ case *ast.FuncLit:
280
+ o.collectFuncLitFacts(model, semPkg, pkg, typed)
281
+ return false
282
+ case *ast.CallExpr:
283
+ o.recordCallSignatureImports(model, semPkg, pkg, typed)
284
+ }
285
+ return true
286
+ })
287
+ }
288
+
289
+ func (o *SemanticModelOwner) collectFuncLitFacts(
290
+ model *SemanticModel,
291
+ semPkg *semanticPackage,
292
+ pkg *packages.Package,
293
+ lit *ast.FuncLit,
294
+ ) {
295
+ ast.Inspect(lit.Body, func(node ast.Node) bool {
296
+ switch typed := node.(type) {
297
+ case *ast.FuncLit:
298
+ o.collectFuncLitFacts(model, semPkg, pkg, typed)
299
+ return false
300
+ case *ast.TypeSpec:
301
+ o.recordTypeSpec(model, semPkg, pkg, typed)
224
302
  case *ast.Ident:
225
303
  o.addDefinedObject(model, semPkg, pkg, typed)
226
304
  case *ast.UnaryExpr:
@@ -233,13 +311,113 @@ func (o *SemanticModelOwner) collectFileFacts(
233
311
  o.recordTypeAssertion(semPkg, pkg, typed)
234
312
  case *ast.ValueSpec:
235
313
  o.recordValueSpecNilFacts(semPkg, pkg, typed)
314
+ names := make([]ast.Expr, 0, len(typed.Names))
315
+ for _, name := range typed.Names {
316
+ names = append(names, name)
317
+ }
318
+ o.recordAsyncCompatibleFunctionAssignments(model, pkg, names, typed.Values)
236
319
  case *ast.AssignStmt:
237
320
  o.recordAssignNilFacts(semPkg, pkg, typed)
321
+ o.recordAsyncCompatibleFunctionAssignments(model, pkg, typed.Lhs, typed.Rhs)
322
+ for _, lhs := range typed.Lhs {
323
+ o.recordFuncLitAssignedCapture(model, pkg, lit, lhs)
324
+ }
325
+ case *ast.CallExpr:
326
+ o.recordCallSignatureImports(model, semPkg, pkg, typed)
327
+ case *ast.IncDecStmt:
328
+ o.recordFuncLitAssignedCapture(model, pkg, lit, typed.X)
238
329
  }
239
330
  return true
240
331
  })
241
332
  }
242
333
 
334
+ func (o *SemanticModelOwner) recordTypeSpec(
335
+ model *SemanticModel,
336
+ semPkg *semanticPackage,
337
+ pkg *packages.Package,
338
+ spec *ast.TypeSpec,
339
+ ) {
340
+ obj, _ := pkg.TypesInfo.Defs[spec.Name].(*types.TypeName)
341
+ if obj == nil {
342
+ return
343
+ }
344
+ position := sourcePos(pkg, spec.Name.Pos())
345
+ o.addType(model, semPkg, obj, position, spec.Type)
346
+ o.recordGeneratedImports(model, semPkg, position.file, pkg.PkgPath, obj.Type())
347
+ }
348
+
349
+ func (o *SemanticModelOwner) recordFuncLitAssignedCapture(
350
+ model *SemanticModel,
351
+ pkg *packages.Package,
352
+ lit *ast.FuncLit,
353
+ expr ast.Expr,
354
+ ) {
355
+ ident, ok := ast.Unparen(expr).(*ast.Ident)
356
+ if !ok {
357
+ return
358
+ }
359
+ obj, _ := pkg.TypesInfo.Uses[ident].(*types.Var)
360
+ if obj == nil || !obj.Pos().IsValid() {
361
+ return
362
+ }
363
+ if lit.Pos() < obj.Pos() && obj.Pos() < lit.End() {
364
+ return
365
+ }
366
+ if signatureForType(obj.Type()) == nil {
367
+ return
368
+ }
369
+ model.needsVarRef[obj] = true
370
+ }
371
+
372
+ func (o *SemanticModelOwner) recordCallSignatureImports(
373
+ model *SemanticModel,
374
+ semPkg *semanticPackage,
375
+ pkg *packages.Package,
376
+ expr *ast.CallExpr,
377
+ ) {
378
+ signature := signatureForType(pkg.TypesInfo.TypeOf(expr.Fun))
379
+ if signature == nil {
380
+ return
381
+ }
382
+ position := sourcePos(pkg, expr.Pos())
383
+ o.recordTupleImports(model, semPkg, position.file, pkg.PkgPath, signature.Params(), make(map[types.Type]bool))
384
+ o.recordTupleImports(model, semPkg, position.file, pkg.PkgPath, signature.Results(), make(map[types.Type]bool))
385
+ }
386
+
387
+ func (o *SemanticModelOwner) recordAsyncCompatibleFunctionAssignments(
388
+ model *SemanticModel,
389
+ pkg *packages.Package,
390
+ lhs []ast.Expr,
391
+ rhs []ast.Expr,
392
+ ) {
393
+ for idx, target := range lhs {
394
+ if idx >= len(rhs) {
395
+ return
396
+ }
397
+ obj := objectForAddress(pkg, target)
398
+ if obj == nil || signatureForType(obj.Type()) == nil {
399
+ continue
400
+ }
401
+ if !exprMayNeedAwait(model, pkg, rhs[idx]) {
402
+ continue
403
+ }
404
+ if value := model.values[obj]; value != nil {
405
+ value.asyncCompatibleFunction = true
406
+ }
407
+ }
408
+ }
409
+
410
+ func signatureForType(typ types.Type) *types.Signature {
411
+ if typ == nil {
412
+ return nil
413
+ }
414
+ if signature, ok := typ.(*types.Signature); ok {
415
+ return signature
416
+ }
417
+ signature, _ := types.Unalias(typ).Underlying().(*types.Signature)
418
+ return signature
419
+ }
420
+
243
421
  func (o *SemanticModelOwner) recordPointerReceiverUse(
244
422
  model *SemanticModel,
245
423
  pkg *packages.Package,
@@ -306,6 +484,9 @@ func (o *SemanticModelOwner) addType(
306
484
  return nil
307
485
  }
308
486
  if existing := model.types[named]; existing != nil {
487
+ if typeExpr != nil && len(existing.fields) == 0 {
488
+ existing.fields = semanticFields(named, typeExpr)
489
+ }
309
490
  return existing
310
491
  }
311
492
  _, isInterface := named.Underlying().(*types.Interface)
@@ -368,6 +549,21 @@ func (o *SemanticModelOwner) addFunction(
368
549
  if existing := model.functions[fn]; existing != nil {
369
550
  return existing
370
551
  }
552
+ if origin := fn.Origin(); origin != nil {
553
+ if existing := model.functions[origin]; existing != nil {
554
+ model.functions[fn] = existing
555
+ return existing
556
+ }
557
+ }
558
+ if fullName := fn.FullName(); fullName != "" {
559
+ if existing := model.functionsByFullName[fullName]; existing != nil {
560
+ model.functions[fn] = existing
561
+ if origin := fn.Origin(); origin != nil {
562
+ model.functions[origin] = existing
563
+ }
564
+ return existing
565
+ }
566
+ }
371
567
  signature, _ := fn.Type().(*types.Signature)
372
568
  semFn := &semanticFunction{
373
569
  name: fn.Name(),
@@ -384,6 +580,14 @@ func (o *SemanticModelOwner) addFunction(
384
580
  semFn.receiver = receiverNamedType(recv)
385
581
  }
386
582
  model.functions[fn] = semFn
583
+ if origin := fn.Origin(); origin != nil {
584
+ model.functions[origin] = semFn
585
+ }
586
+ if fullName := fn.FullName(); fullName != "" {
587
+ if existing := model.functionsByFullName[fullName]; existing == nil {
588
+ model.functionsByFullName[fullName] = semFn
589
+ }
590
+ }
387
591
  semPkg.functions = append(semPkg.functions, semFn)
388
592
  return semFn
389
593
  }
@@ -461,6 +665,7 @@ func (o *SemanticModelOwner) collectFunctionFacts(
461
665
  model *SemanticModel,
462
666
  pkg *packages.Package,
463
667
  file *ast.File,
668
+ overrideFacts *OverrideFacts,
464
669
  ) []Diagnostic {
465
670
  var diagnostics []Diagnostic
466
671
  for _, decl := range file.Decls {
@@ -487,19 +692,21 @@ func (o *SemanticModelOwner) collectFunctionFacts(
487
692
  }
488
693
  case *ast.CallExpr:
489
694
  if called := calledFunction(pkg, typed.Fun); called != nil {
490
- semFn.calls[called] = true
695
+ semFn.calls[functionOriginOrSelf(called)] = true
491
696
  }
492
- async, err := o.isOverrideAsyncCall(pkg, typed.Fun)
493
- if err != nil {
494
- diagnostics = append(diagnostics, Diagnostic{
495
- Severity: DiagnosticSeverityError,
496
- Code: "goscript/overrides:metadata",
497
- Message: "failed to read override metadata",
498
- Detail: err.Error(),
499
- })
500
- return false
697
+ if fun, ok := ast.Unparen(typed.Fun).(*ast.FuncLit); ok {
698
+ recordImmediateFuncLitAsyncFacts(model, pkg, overrideFacts, semFn, fun)
699
+ }
700
+ if callUsesFunctionValue(pkg, typed.Fun) {
701
+ markFunctionAsync(semFn, "function-value-call")
501
702
  }
502
- if async {
703
+ if callUsesFunctionIdentifier(pkg, typed.Fun) {
704
+ markFunctionAsync(semFn, "function-identifier-call")
705
+ }
706
+ if overrideFacts.IsMethodAsync(overrideCallPackage(pkg, typed.Fun), overrideCallMethod(pkg, typed.Fun)) {
707
+ markFunctionAsync(semFn, "override")
708
+ }
709
+ if overrideFacts.IsFunctionAsync(overrideFunctionCallPackage(pkg, typed.Fun), overrideFunctionCallName(pkg, typed.Fun)) {
503
710
  markFunctionAsync(semFn, "override")
504
711
  }
505
712
  }
@@ -509,28 +716,247 @@ func (o *SemanticModelOwner) collectFunctionFacts(
509
716
  return diagnostics
510
717
  }
511
718
 
512
- func (o *SemanticModelOwner) isOverrideAsyncCall(pkg *packages.Package, expr ast.Expr) (bool, error) {
719
+ func recordImmediateFuncLitAsyncFacts(
720
+ model *SemanticModel,
721
+ pkg *packages.Package,
722
+ overrideFacts *OverrideFacts,
723
+ semFn *semanticFunction,
724
+ lit *ast.FuncLit,
725
+ ) {
726
+ if lit == nil || lit.Body == nil {
727
+ return
728
+ }
729
+ ast.Inspect(lit.Body, func(node ast.Node) bool {
730
+ switch typed := node.(type) {
731
+ case *ast.FuncLit:
732
+ return false
733
+ case *ast.SendStmt:
734
+ markFunctionAsync(semFn, "async-function-literal-call")
735
+ case *ast.SelectStmt:
736
+ markFunctionAsync(semFn, "async-function-literal-call")
737
+ case *ast.UnaryExpr:
738
+ if typed.Op == token.ARROW {
739
+ markFunctionAsync(semFn, "async-function-literal-call")
740
+ }
741
+ case *ast.CallExpr:
742
+ called := calledFunction(pkg, typed.Fun)
743
+ if called != nil {
744
+ semFn.calls[functionOriginOrSelf(called)] = true
745
+ }
746
+ if callUsesFunctionValue(pkg, typed.Fun) {
747
+ markFunctionAsync(semFn, "async-function-literal-call")
748
+ }
749
+ if callUsesFunctionIdentifier(pkg, typed.Fun) {
750
+ markFunctionAsync(semFn, "async-function-literal-call")
751
+ }
752
+ if called != nil {
753
+ calledFn := semanticFunctionFor(model, called)
754
+ if calledFn != nil && calledFn.async {
755
+ markFunctionAsync(semFn, "async-function-literal-call")
756
+ }
757
+ }
758
+ if overrideFacts.IsMethodAsync(overrideCallPackage(pkg, typed.Fun), overrideCallMethod(pkg, typed.Fun)) {
759
+ markFunctionAsync(semFn, "async-function-literal-call")
760
+ }
761
+ if overrideFacts.IsFunctionAsync(overrideFunctionCallPackage(pkg, typed.Fun), overrideFunctionCallName(pkg, typed.Fun)) {
762
+ markFunctionAsync(semFn, "async-function-literal-call")
763
+ }
764
+ }
765
+ return true
766
+ })
767
+ }
768
+
769
+ func (o *SemanticModelOwner) propagateAsyncFunctionArguments(
770
+ ctx context.Context,
771
+ model *SemanticModel,
772
+ ) []Diagnostic {
773
+ changed := true
774
+ for changed {
775
+ if err := ctx.Err(); err != nil {
776
+ return []Diagnostic{contextCanceledDiagnostic(err)}
777
+ }
778
+ changed = false
779
+ for _, semPkg := range model.packages {
780
+ if err := ctx.Err(); err != nil {
781
+ return []Diagnostic{contextCanceledDiagnostic(err)}
782
+ }
783
+ pkg := semPkg.source
784
+ if pkg == nil {
785
+ continue
786
+ }
787
+ for _, file := range pkg.Syntax {
788
+ if err := ctx.Err(); err != nil {
789
+ return []Diagnostic{contextCanceledDiagnostic(err)}
790
+ }
791
+ var inspectErr error
792
+ ast.Inspect(file, func(node ast.Node) bool {
793
+ if inspectErr = ctx.Err(); inspectErr != nil {
794
+ return false
795
+ }
796
+ switch typed := node.(type) {
797
+ case *ast.CallExpr:
798
+ called := calledFunction(pkg, typed.Fun)
799
+ semFn := semanticFunctionFor(model, called)
800
+ if semFn == nil || !semFn.hasBody {
801
+ return true
802
+ }
803
+ signature, _ := called.Type().(*types.Signature)
804
+ if callPassesAsyncFunctionArgument(model, pkg, signature, typed.Args) {
805
+ if markFunctionAsync(semFn, "async-function-argument") {
806
+ changed = true
807
+ }
808
+ }
809
+ }
810
+ return true
811
+ })
812
+ if inspectErr != nil {
813
+ return []Diagnostic{contextCanceledDiagnostic(inspectErr)}
814
+ }
815
+ }
816
+ }
817
+ if changed {
818
+ if diagnostics := o.propagateFunctionAsync(ctx, model); diagnosticsHaveErrors(diagnostics) {
819
+ return diagnostics
820
+ }
821
+ }
822
+ }
823
+ return nil
824
+ }
825
+
826
+ func overrideCallPackage(pkg *packages.Package, expr ast.Expr) string {
513
827
  selector, ok := expr.(*ast.SelectorExpr)
514
828
  if !ok {
515
- return false, nil
829
+ return ""
516
830
  }
517
831
  selection := pkg.TypesInfo.Selections[selector]
518
832
  if selection == nil {
519
- return false, nil
833
+ return ""
520
834
  }
521
835
  method, _ := selection.Obj().(*types.Func)
522
836
  if method == nil {
523
- return false, nil
837
+ return ""
524
838
  }
525
- named := receiverNamedType(selection.Recv())
839
+ named := selectedReceiverNamedType(pkg, selector, selection)
526
840
  if named == nil || named.Obj() == nil || named.Obj().Pkg() == nil {
527
- return false, nil
841
+ return ""
842
+ }
843
+ return named.Obj().Pkg().Path()
844
+ }
845
+
846
+ func overrideCallMethod(pkg *packages.Package, expr ast.Expr) string {
847
+ selector, ok := expr.(*ast.SelectorExpr)
848
+ if !ok {
849
+ return ""
850
+ }
851
+ selection := pkg.TypesInfo.Selections[selector]
852
+ if selection == nil {
853
+ return ""
854
+ }
855
+ method, _ := selection.Obj().(*types.Func)
856
+ if method == nil {
857
+ return ""
858
+ }
859
+ named := selectedReceiverNamedType(pkg, selector, selection)
860
+ if named == nil || named.Obj() == nil {
861
+ return ""
862
+ }
863
+ return named.Obj().Name() + "." + method.Name()
864
+ }
865
+
866
+ func selectedReceiverNamedType(pkg *packages.Package, selector *ast.SelectorExpr, selection *types.Selection) *types.Named {
867
+ if named := promotedReceiverNamedType(selection); named != nil {
868
+ return named
869
+ }
870
+ if named := receiverNamedType(selection.Recv()); named != nil {
871
+ return named
872
+ }
873
+ if pkg == nil || selector == nil {
874
+ return nil
528
875
  }
529
- methodKey := named.Obj().Name() + "." + method.Name()
530
- return o.overrideOwner.IsMethodAsync(named.Obj().Pkg().Path(), methodKey)
876
+ return receiverNamedType(pkg.TypesInfo.TypeOf(selector.X))
877
+ }
878
+
879
+ func promotedReceiverNamedType(selection *types.Selection) *types.Named {
880
+ index := selection.Index()
881
+ if len(index) <= 1 {
882
+ return nil
883
+ }
884
+ typ := selection.Recv()
885
+ for _, idx := range index[:len(index)-1] {
886
+ for {
887
+ if pointer, ok := types.Unalias(typ).(*types.Pointer); ok {
888
+ typ = pointer.Elem()
889
+ continue
890
+ }
891
+ break
892
+ }
893
+ switch underlying := types.Unalias(typ).Underlying().(type) {
894
+ case *types.Struct:
895
+ if idx < 0 || idx >= underlying.NumFields() {
896
+ return nil
897
+ }
898
+ typ = underlying.Field(idx).Type()
899
+ default:
900
+ return receiverNamedType(typ)
901
+ }
902
+ }
903
+ return receiverNamedType(typ)
904
+ }
905
+
906
+ func overrideFunctionCallPackage(pkg *packages.Package, expr ast.Expr) string {
907
+ fn := calledFunction(pkg, expr)
908
+ if fn == nil || fn.Pkg() == nil {
909
+ return ""
910
+ }
911
+ return fn.Pkg().Path()
912
+ }
913
+
914
+ func overrideFunctionCallName(pkg *packages.Package, expr ast.Expr) string {
915
+ fn := calledFunction(pkg, expr)
916
+ if fn == nil {
917
+ return ""
918
+ }
919
+ return fn.Name()
920
+ }
921
+
922
+ func semanticFunctionFor(model *SemanticModel, fn *types.Func) *semanticFunction {
923
+ if model == nil || fn == nil {
924
+ return nil
925
+ }
926
+ if semFn := model.functions[fn]; semFn != nil {
927
+ return semFn
928
+ }
929
+ if origin := fn.Origin(); origin != nil {
930
+ if semFn := model.functions[origin]; semFn != nil {
931
+ model.functions[fn] = semFn
932
+ return semFn
933
+ }
934
+ }
935
+ if fullName := fn.FullName(); fullName != "" {
936
+ if semFn := model.functionsByFullName[fullName]; semFn != nil {
937
+ model.functions[fn] = semFn
938
+ return semFn
939
+ }
940
+ }
941
+ if model.functionLookupMisses[fn] {
942
+ return nil
943
+ }
944
+ model.functionLookupMisses[fn] = true
945
+ return nil
531
946
  }
532
947
 
533
948
  func calledFunction(pkg *packages.Package, expr ast.Expr) *types.Func {
949
+ for {
950
+ switch typed := expr.(type) {
951
+ case *ast.IndexExpr:
952
+ expr = typed.X
953
+ case *ast.IndexListExpr:
954
+ expr = typed.X
955
+ default:
956
+ goto unwrapped
957
+ }
958
+ }
959
+ unwrapped:
534
960
  switch typed := expr.(type) {
535
961
  case *ast.Ident:
536
962
  fn, _ := pkg.TypesInfo.Uses[typed].(*types.Func)
@@ -546,6 +972,135 @@ func calledFunction(pkg *packages.Package, expr ast.Expr) *types.Func {
546
972
  return nil
547
973
  }
548
974
 
975
+ func functionOriginOrSelf(fn *types.Func) *types.Func {
976
+ if fn == nil {
977
+ return nil
978
+ }
979
+ if origin := fn.Origin(); origin != nil {
980
+ return origin
981
+ }
982
+ return fn
983
+ }
984
+
985
+ func callUsesFunctionValue(pkg *packages.Package, expr ast.Expr) bool {
986
+ if signatureForType(pkg.TypesInfo.TypeOf(expr)) == nil {
987
+ return false
988
+ }
989
+ switch typed := expr.(type) {
990
+ case *ast.CallExpr:
991
+ return true
992
+ case *ast.SelectorExpr:
993
+ selection := pkg.TypesInfo.Selections[typed]
994
+ if selection != nil {
995
+ return selection.Kind() == types.FieldVal && signatureForType(selection.Type()) != nil
996
+ }
997
+ obj, _ := pkg.TypesInfo.Uses[typed.Sel].(*types.Var)
998
+ return obj != nil && signatureForType(obj.Type()) != nil
999
+ case *ast.IndexExpr:
1000
+ if signatureForType(pkg.TypesInfo.TypeOf(typed.X)) != nil {
1001
+ return false
1002
+ }
1003
+ return true
1004
+ case *ast.IndexListExpr:
1005
+ if signatureForType(pkg.TypesInfo.TypeOf(typed.X)) != nil {
1006
+ return false
1007
+ }
1008
+ return true
1009
+ default:
1010
+ return false
1011
+ }
1012
+ }
1013
+
1014
+ func callUsesFunctionIdentifier(pkg *packages.Package, expr ast.Expr) bool {
1015
+ if signatureForType(pkg.TypesInfo.TypeOf(expr)) == nil {
1016
+ return false
1017
+ }
1018
+ ident, ok := expr.(*ast.Ident)
1019
+ if !ok {
1020
+ return false
1021
+ }
1022
+ obj := pkg.TypesInfo.Uses[ident]
1023
+ if obj == nil {
1024
+ obj = pkg.TypesInfo.Defs[ident]
1025
+ }
1026
+ _, ok = obj.(*types.Var)
1027
+ return ok
1028
+ }
1029
+
1030
+ func callPassesAsyncFunctionArgument(
1031
+ model *SemanticModel,
1032
+ pkg *packages.Package,
1033
+ signature *types.Signature,
1034
+ args []ast.Expr,
1035
+ ) bool {
1036
+ if signature == nil || signature.Params() == nil {
1037
+ return false
1038
+ }
1039
+ for idx, arg := range args {
1040
+ paramIdx := idx
1041
+ if signature.Variadic() && idx >= signature.Params().Len()-1 {
1042
+ paramIdx = signature.Params().Len() - 1
1043
+ }
1044
+ if paramIdx < 0 || paramIdx >= signature.Params().Len() {
1045
+ continue
1046
+ }
1047
+ if signatureForType(signature.Params().At(paramIdx).Type()) == nil {
1048
+ continue
1049
+ }
1050
+ if exprMayNeedAwait(model, pkg, arg) {
1051
+ return true
1052
+ }
1053
+ }
1054
+ return false
1055
+ }
1056
+
1057
+ func exprMayNeedAwait(model *SemanticModel, pkg *packages.Package, expr ast.Expr) bool {
1058
+ if called := calledFunction(pkg, expr); called != nil {
1059
+ semFn := semanticFunctionFor(model, called)
1060
+ return semFn != nil && semFn.async
1061
+ }
1062
+ lit, ok := expr.(*ast.FuncLit)
1063
+ if !ok {
1064
+ return false
1065
+ }
1066
+ needsAwait := false
1067
+ ast.Inspect(lit.Body, func(node ast.Node) bool {
1068
+ if needsAwait {
1069
+ return false
1070
+ }
1071
+ switch typed := node.(type) {
1072
+ case *ast.FuncLit:
1073
+ return false
1074
+ case *ast.SendStmt, *ast.SelectStmt:
1075
+ needsAwait = true
1076
+ return false
1077
+ case *ast.UnaryExpr:
1078
+ if typed.Op == token.ARROW {
1079
+ needsAwait = true
1080
+ return false
1081
+ }
1082
+ case *ast.CallExpr:
1083
+ if callUsesFunctionValue(pkg, typed.Fun) {
1084
+ needsAwait = true
1085
+ return false
1086
+ }
1087
+ if callUsesFunctionIdentifier(pkg, typed.Fun) {
1088
+ needsAwait = true
1089
+ return false
1090
+ }
1091
+ if called := calledFunction(pkg, typed.Fun); called != nil {
1092
+ semFn := semanticFunctionFor(model, called)
1093
+ if semFn != nil && semFn.async {
1094
+ needsAwait = true
1095
+ return false
1096
+ }
1097
+ }
1098
+ }
1099
+ return true
1100
+ })
1101
+ return needsAwait
1102
+ }
1103
+
549
1104
  func receiverNamedType(typ types.Type) *types.Named {
550
1105
  for {
551
1106
  pointer, ok := typ.(*types.Pointer)
@@ -554,17 +1109,23 @@ func receiverNamedType(typ types.Type) *types.Named {
554
1109
  }
555
1110
  typ = pointer.Elem()
556
1111
  }
557
- named, _ := typ.(*types.Named)
1112
+ named, _ := types.Unalias(typ).(*types.Named)
558
1113
  return named
559
1114
  }
560
1115
 
561
- func (o *SemanticModelOwner) propagateFunctionAsync(model *SemanticModel) {
1116
+ func (o *SemanticModelOwner) propagateFunctionAsync(ctx context.Context, model *SemanticModel) []Diagnostic {
562
1117
  changed := true
563
1118
  for changed {
1119
+ if err := ctx.Err(); err != nil {
1120
+ return []Diagnostic{contextCanceledDiagnostic(err)}
1121
+ }
564
1122
  changed = false
565
1123
  for _, semFn := range model.functions {
1124
+ if err := ctx.Err(); err != nil {
1125
+ return []Diagnostic{contextCanceledDiagnostic(err)}
1126
+ }
566
1127
  for called := range semFn.calls {
567
- calledFn := model.functions[called]
1128
+ calledFn := semanticFunctionFor(model, called)
568
1129
  if calledFn != nil && calledFn.async {
569
1130
  if markFunctionAsync(semFn, "call:"+called.FullName()) {
570
1131
  changed = true
@@ -573,6 +1134,7 @@ func (o *SemanticModelOwner) propagateFunctionAsync(model *SemanticModel) {
573
1134
  }
574
1135
  }
575
1136
  }
1137
+ return nil
576
1138
  }
577
1139
 
578
1140
  func markFunctionAsync(fn *semanticFunction, reason string) bool {
@@ -588,10 +1150,29 @@ func markFunctionAsync(fn *semanticFunction, reason string) bool {
588
1150
  return true
589
1151
  }
590
1152
 
591
- func (o *SemanticModelOwner) resolveInterfaceImplementations(model *SemanticModel) {
1153
+ func semanticAsyncFunctionCount(model *SemanticModel) int {
1154
+ if model == nil {
1155
+ return 0
1156
+ }
1157
+ count := 0
1158
+ for _, fn := range model.functions {
1159
+ if fn != nil && fn.async {
1160
+ count++
1161
+ }
1162
+ }
1163
+ return count
1164
+ }
1165
+
1166
+ func (o *SemanticModelOwner) resolveInterfaceImplementationGraph(
1167
+ ctx context.Context,
1168
+ model *SemanticModel,
1169
+ ) ([]semanticInterfaceImplementationGraphEntry, []Diagnostic) {
592
1170
  var interfaces []*types.Named
593
1171
  var concretes []*types.Named
594
1172
  for named, semType := range model.types {
1173
+ if err := ctx.Err(); err != nil {
1174
+ return nil, []Diagnostic{contextCanceledDiagnostic(err)}
1175
+ }
595
1176
  if semType.isInterface {
596
1177
  interfaces = append(interfaces, named)
597
1178
  continue
@@ -600,64 +1181,201 @@ func (o *SemanticModelOwner) resolveInterfaceImplementations(model *SemanticMode
600
1181
  }
601
1182
  sortNamedTypes(interfaces)
602
1183
  sortNamedTypes(concretes)
1184
+ methodSets := implementationMethodSets(concretes)
603
1185
 
1186
+ implementationGraph := make([]semanticInterfaceImplementationGraphEntry, 0)
604
1187
  for _, ifaceNamed := range interfaces {
1188
+ if err := ctx.Err(); err != nil {
1189
+ return nil, []Diagnostic{contextCanceledDiagnostic(err)}
1190
+ }
605
1191
  iface, _ := ifaceNamed.Underlying().(*types.Interface)
606
1192
  if iface == nil {
607
1193
  continue
608
1194
  }
609
1195
  iface.Complete()
610
- for _, concrete := range concretes {
611
- o.addInterfaceImplementation(model, concrete, ifaceNamed, iface, false)
612
- o.addInterfaceImplementation(model, concrete, ifaceNamed, iface, true)
1196
+ ifaceMethods := interfaceMethodMap(iface)
1197
+ if len(ifaceMethods) == 0 {
1198
+ continue
1199
+ }
1200
+ for _, methodSet := range methodSets {
1201
+ if err := ctx.Err(); err != nil {
1202
+ return nil, []Diagnostic{contextCanceledDiagnostic(err)}
1203
+ }
1204
+ if implementation, ok := o.interfaceImplementationGraphEntry(methodSet, ifaceNamed, ifaceMethods); ok {
1205
+ implementationGraph = append(implementationGraph, implementation)
1206
+ }
613
1207
  }
614
1208
  }
1209
+ return implementationGraph, nil
615
1210
  }
616
1211
 
617
- func (o *SemanticModelOwner) addInterfaceImplementation(
1212
+ func (o *SemanticModelOwner) applyInterfaceAsyncMethods(
1213
+ ctx context.Context,
618
1214
  model *SemanticModel,
619
- concrete *types.Named,
620
- ifaceNamed *types.Named,
621
- iface *types.Interface,
622
- pointer bool,
623
- ) {
624
- var receiver types.Type = concrete
625
- if pointer {
626
- receiver = types.NewPointer(concrete)
1215
+ interfaceGraph []semanticInterfaceImplementationGraphEntry,
1216
+ ) []Diagnostic {
1217
+ model.interfaceImplementations = model.interfaceImplementations[:0]
1218
+ for _, graphEntry := range interfaceGraph {
1219
+ if err := ctx.Err(); err != nil {
1220
+ return []Diagnostic{contextCanceledDiagnostic(err)}
1221
+ }
1222
+ implementation := semanticInterfaceImplementation{
1223
+ typ: graphEntry.typ,
1224
+ iface: graphEntry.iface,
1225
+ pointer: graphEntry.pointer,
1226
+ asyncMethods: make(map[string]bool),
1227
+ }
1228
+ for methodName, implMethod := range graphEntry.implMethods {
1229
+ implFn := model.functions[implMethod]
1230
+ if implFn != nil && implFn.async {
1231
+ implementation.asyncMethods[methodName] = true
1232
+ if ifaceFn := model.functions[graphEntry.ifaceMethods[methodName]]; ifaceFn != nil {
1233
+ markFunctionAsync(ifaceFn, "interface-implementation")
1234
+ }
1235
+ }
1236
+ }
1237
+ for methodName, async := range implementation.asyncMethods {
1238
+ if !async {
1239
+ continue
1240
+ }
1241
+ markFunctionAsync(model.functions[graphEntry.implMethods[methodName]], "interface-method")
1242
+ }
1243
+ model.interfaceImplementations = append(model.interfaceImplementations, implementation)
627
1244
  }
628
- if !types.Implements(receiver, iface) {
629
- return
1245
+ return nil
1246
+ }
1247
+
1248
+ func contextCanceledDiagnostic(err error) Diagnostic {
1249
+ return Diagnostic{
1250
+ Severity: DiagnosticSeverityError,
1251
+ Code: "goscript/context:canceled",
1252
+ Message: err.Error(),
630
1253
  }
1254
+ }
631
1255
 
632
- implementation := semanticInterfaceImplementation{
633
- typ: concrete,
634
- iface: ifaceNamed,
635
- pointer: pointer,
636
- asyncMethods: make(map[string]bool),
1256
+ func (o *SemanticModelOwner) interfaceImplementationGraphEntry(
1257
+ methodSet semanticImplementationMethodSet,
1258
+ ifaceNamed *types.Named,
1259
+ ifaceMethods map[string]*types.Func,
1260
+ ) (semanticInterfaceImplementationGraphEntry, bool) {
1261
+ if !implementationHasMethods(methodSet.methods, ifaceMethods) {
1262
+ return semanticInterfaceImplementationGraphEntry{}, false
637
1263
  }
638
- for ifaceMethod := range iface.Methods() {
639
- obj, _, _ := types.LookupFieldOrMethod(receiver, true, concrete.Obj().Pkg(), ifaceMethod.Name())
640
- implMethod, _ := obj.(*types.Func)
641
- if implMethod == nil {
642
- continue
1264
+
1265
+ implementsReceiver := methodSet.receiver
1266
+ implementsIface := types.Type(ifaceNamed.Underlying())
1267
+ if methodSet.typ.TypeParams() != nil && methodSet.typ.TypeParams().Len() != 0 {
1268
+ args := typeParamTypes(methodSet.typ.TypeParams())
1269
+ if instantiated, err := types.Instantiate(nil, methodSet.typ, args, false); err == nil {
1270
+ implementsReceiver = instantiated
1271
+ if methodSet.pointer {
1272
+ implementsReceiver = types.NewPointer(instantiated)
1273
+ }
643
1274
  }
644
- implFn := model.functions[implMethod]
645
- if implFn != nil && implFn.async {
646
- implementation.asyncMethods[ifaceMethod.Name()] = true
647
- if ifaceFn := model.functions[ifaceMethod]; ifaceFn != nil {
648
- markFunctionAsync(ifaceFn, "interface-implementation")
1275
+ if ifaceNamed.TypeParams() != nil && ifaceNamed.TypeParams().Len() == len(args) {
1276
+ if instantiated, err := types.Instantiate(nil, ifaceNamed, args, false); err == nil {
1277
+ implementsIface = instantiated.Underlying()
649
1278
  }
650
1279
  }
651
1280
  }
652
- for methodName, async := range implementation.asyncMethods {
653
- if !async {
654
- continue
1281
+ if !types.Implements(implementsReceiver, implementsIface.Underlying().(*types.Interface)) {
1282
+ return semanticInterfaceImplementationGraphEntry{}, false
1283
+ }
1284
+
1285
+ implementation := semanticInterfaceImplementationGraphEntry{
1286
+ typ: methodSet.typ,
1287
+ iface: ifaceNamed,
1288
+ pointer: methodSet.pointer,
1289
+ ifaceMethods: make(map[string]*types.Func),
1290
+ implMethods: implementationMethodMap(methodSet.methods, ifaceMethods),
1291
+ }
1292
+ maps.Copy(implementation.ifaceMethods, ifaceMethods)
1293
+ return implementation, true
1294
+ }
1295
+
1296
+ func interfaceMethodMap(iface *types.Interface) map[string]*types.Func {
1297
+ if iface == nil {
1298
+ return nil
1299
+ }
1300
+ methods := make(map[string]*types.Func)
1301
+ for method := range iface.Methods() {
1302
+ methods[method.Name()] = method
1303
+ }
1304
+ return methods
1305
+ }
1306
+
1307
+ func implementationMethodSets(concretes []*types.Named) []semanticImplementationMethodSet {
1308
+ methodSets := make([]semanticImplementationMethodSet, 0, len(concretes)*2)
1309
+ for _, concrete := range concretes {
1310
+ methodSets = append(methodSets, semanticImplementationMethodSet{
1311
+ typ: concrete,
1312
+ receiver: concrete,
1313
+ methods: methodSetMap(concrete),
1314
+ })
1315
+ pointer := types.NewPointer(concrete)
1316
+ methodSets = append(methodSets, semanticImplementationMethodSet{
1317
+ typ: concrete,
1318
+ receiver: pointer,
1319
+ pointer: true,
1320
+ methods: methodSetMap(pointer),
1321
+ })
1322
+ }
1323
+ return methodSets
1324
+ }
1325
+
1326
+ func methodSetMap(receiver types.Type) map[string]*types.Func {
1327
+ if receiver == nil {
1328
+ return nil
1329
+ }
1330
+ set := types.NewMethodSet(receiver)
1331
+ if set.Len() == 0 {
1332
+ return nil
1333
+ }
1334
+ methods := make(map[string]*types.Func, set.Len())
1335
+ for method := range set.Methods() {
1336
+ fn, _ := method.Obj().(*types.Func)
1337
+ if fn != nil {
1338
+ methods[fn.Name()] = fn
1339
+ }
1340
+ }
1341
+ return methods
1342
+ }
1343
+
1344
+ func implementationHasMethods(
1345
+ receiverMethods map[string]*types.Func,
1346
+ ifaceMethods map[string]*types.Func,
1347
+ ) bool {
1348
+ if len(receiverMethods) == 0 || len(ifaceMethods) == 0 {
1349
+ return false
1350
+ }
1351
+ for methodName := range ifaceMethods {
1352
+ if receiverMethods[methodName] == nil {
1353
+ return false
655
1354
  }
656
- obj, _, _ := types.LookupFieldOrMethod(receiver, true, concrete.Obj().Pkg(), methodName)
657
- implMethod, _ := obj.(*types.Func)
658
- markFunctionAsync(model.functions[implMethod], "interface-method")
659
1355
  }
660
- model.interfaceImplementations = append(model.interfaceImplementations, implementation)
1356
+ return true
1357
+ }
1358
+
1359
+ func implementationMethodMap(
1360
+ receiverMethods map[string]*types.Func,
1361
+ ifaceMethods map[string]*types.Func,
1362
+ ) map[string]*types.Func {
1363
+ methods := make(map[string]*types.Func, len(ifaceMethods))
1364
+ for methodName := range ifaceMethods {
1365
+ methods[methodName] = receiverMethods[methodName]
1366
+ }
1367
+ return methods
1368
+ }
1369
+
1370
+ func typeParamTypes(params *types.TypeParamList) []types.Type {
1371
+ if params == nil {
1372
+ return nil
1373
+ }
1374
+ args := make([]types.Type, 0, params.Len())
1375
+ for tparam := range params.TypeParams() {
1376
+ args = append(args, tparam)
1377
+ }
1378
+ return args
661
1379
  }
662
1380
 
663
1381
  func sortNamedTypes(named []*types.Named) {
@@ -774,6 +1492,18 @@ func isInterfaceType(typ types.Type) bool {
774
1492
  return ok
775
1493
  }
776
1494
 
1495
+ func isNonEmptyInterfaceType(typ types.Type) bool {
1496
+ if typ == nil {
1497
+ return false
1498
+ }
1499
+ iface, ok := types.Unalias(typ).Underlying().(*types.Interface)
1500
+ if !ok {
1501
+ return false
1502
+ }
1503
+ iface.Complete()
1504
+ return iface.NumMethods() != 0
1505
+ }
1506
+
777
1507
  func isNilableType(typ types.Type) bool {
778
1508
  if typ == nil {
779
1509
  return false
@@ -812,6 +1542,19 @@ func (o *SemanticModelOwner) recordTypeImports(
812
1542
  }
813
1543
  seen[typ] = true
814
1544
 
1545
+ if alias, ok := typ.(*types.Alias); ok {
1546
+ if obj := alias.Obj(); obj != nil && obj.Pkg() != nil && obj.Pkg().Path() != currentPkg {
1547
+ addGeneratedImport(model, semPkg, file, obj.Pkg().Path())
1548
+ }
1549
+ if args := alias.TypeArgs(); args != nil {
1550
+ for t := range args.Types() {
1551
+ o.recordTypeImports(model, semPkg, file, currentPkg, t, seen)
1552
+ }
1553
+ }
1554
+ o.recordTypeImports(model, semPkg, file, currentPkg, alias.Rhs(), seen)
1555
+ return
1556
+ }
1557
+
815
1558
  switch typed := types.Unalias(typ).(type) {
816
1559
  case *types.Named:
817
1560
  if obj := typed.Obj(); obj != nil && obj.Pkg() != nil && obj.Pkg().Path() != currentPkg {
@@ -822,7 +1565,9 @@ func (o *SemanticModelOwner) recordTypeImports(
822
1565
  o.recordTypeImports(model, semPkg, file, currentPkg, t, seen)
823
1566
  }
824
1567
  }
825
- o.recordTypeImports(model, semPkg, file, currentPkg, typed.Underlying(), seen)
1568
+ if obj := typed.Obj(); obj != nil && obj.Pkg() != nil && obj.Pkg().Path() == currentPkg {
1569
+ o.recordTypeImports(model, semPkg, file, currentPkg, typed.Underlying(), seen)
1570
+ }
826
1571
  case *types.Pointer:
827
1572
  o.recordTypeImports(model, semPkg, file, currentPkg, typed.Elem(), seen)
828
1573
  case *types.Slice: