goscript 0.0.83 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/README.md +13 -1
  2. package/cmd/goscript/cmd_compile.go +70 -69
  3. package/cmd/goscript/cmd_compile_test.go +79 -0
  4. package/cmd/goscript/main.go +10 -5
  5. package/compiler/compile-request.go +218 -0
  6. package/compiler/compiler.go +16 -1336
  7. package/compiler/compliance_test.go +196 -0
  8. package/compiler/config.go +6 -13
  9. package/compiler/diagnostic.go +70 -0
  10. package/compiler/index.test.ts +28 -28
  11. package/compiler/index.ts +40 -72
  12. package/compiler/lowered-program.go +132 -0
  13. package/compiler/lowering.go +3576 -0
  14. package/compiler/override-registry.go +422 -0
  15. package/compiler/override-registry_test.go +207 -0
  16. package/compiler/package-graph.go +231 -0
  17. package/compiler/package-graph_test.go +281 -0
  18. package/compiler/result.go +13 -0
  19. package/compiler/runtime-contract.go +279 -0
  20. package/compiler/runtime-contract_test.go +90 -0
  21. package/compiler/semantic-model-types.go +110 -0
  22. package/compiler/semantic-model.go +922 -0
  23. package/compiler/semantic-model_test.go +416 -0
  24. package/compiler/service.go +133 -0
  25. package/compiler/skeleton_test.go +1145 -0
  26. package/compiler/typescript-emitter.go +663 -0
  27. package/compiler/wasm/compile.go +2 -3
  28. package/compiler/wasm/compile_test.go +29 -0
  29. package/compiler/wasm_api.go +10 -159
  30. package/dist/compiler/index.d.ts +1 -3
  31. package/dist/compiler/index.js +31 -55
  32. package/dist/compiler/index.js.map +1 -1
  33. package/dist/gs/builtin/builtin.d.ts +13 -0
  34. package/dist/gs/builtin/builtin.js +27 -7
  35. package/dist/gs/builtin/builtin.js.map +1 -1
  36. package/dist/gs/builtin/channel.d.ts +3 -3
  37. package/dist/gs/builtin/channel.js.map +1 -1
  38. package/dist/gs/builtin/hostio.d.ts +86 -0
  39. package/dist/gs/builtin/hostio.js +266 -0
  40. package/dist/gs/builtin/hostio.js.map +1 -0
  41. package/dist/gs/builtin/index.d.ts +1 -0
  42. package/dist/gs/builtin/index.js +1 -0
  43. package/dist/gs/builtin/index.js.map +1 -1
  44. package/dist/gs/builtin/print.d.ts +8 -0
  45. package/dist/gs/builtin/print.js +111 -0
  46. package/dist/gs/builtin/print.js.map +1 -0
  47. package/dist/gs/builtin/slice.d.ts +1 -1
  48. package/dist/gs/builtin/slice.js.map +1 -1
  49. package/dist/gs/builtin/type.d.ts +11 -0
  50. package/dist/gs/builtin/type.js +55 -1
  51. package/dist/gs/builtin/type.js.map +1 -1
  52. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  53. package/dist/gs/bytes/bytes.gs.js.map +1 -1
  54. package/dist/gs/bytes/reader.gs.js.map +1 -1
  55. package/dist/gs/context/context.js.map +1 -1
  56. package/dist/gs/crypto/rand/index.d.ts +5 -0
  57. package/dist/gs/crypto/rand/index.js +77 -0
  58. package/dist/gs/crypto/rand/index.js.map +1 -0
  59. package/dist/gs/encoding/json/index.d.ts +3 -0
  60. package/dist/gs/encoding/json/index.js +160 -0
  61. package/dist/gs/encoding/json/index.js.map +1 -0
  62. package/dist/gs/fmt/fmt.js +2 -22
  63. package/dist/gs/fmt/fmt.js.map +1 -1
  64. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +1 -1
  65. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +1 -1
  66. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  67. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  68. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  69. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
  70. package/dist/gs/go/scanner/index.d.ts +29 -0
  71. package/dist/gs/go/scanner/index.js +120 -0
  72. package/dist/gs/go/scanner/index.js.map +1 -0
  73. package/dist/gs/go/token/index.d.ts +31 -0
  74. package/dist/gs/go/token/index.js +82 -0
  75. package/dist/gs/go/token/index.js.map +1 -0
  76. package/dist/gs/internal/abi/index.js.map +1 -1
  77. package/dist/gs/io/fs/fs.js.map +1 -1
  78. package/dist/gs/io/fs/readdir.js.map +1 -1
  79. package/dist/gs/io/fs/readfile.js.map +1 -1
  80. package/dist/gs/io/fs/stat.js.map +1 -1
  81. package/dist/gs/io/fs/sub.js.map +1 -1
  82. package/dist/gs/io/io.js.map +1 -1
  83. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  84. package/dist/gs/os/error.gs.js +2 -4
  85. package/dist/gs/os/error.gs.js.map +1 -1
  86. package/dist/gs/os/exec.gs.js.map +1 -1
  87. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  88. package/dist/gs/os/rawconn_js.gs.js.map +1 -1
  89. package/dist/gs/os/root_js.gs.js.map +1 -1
  90. package/dist/gs/os/tempfile.gs.js +66 -9
  91. package/dist/gs/os/tempfile.gs.js.map +1 -1
  92. package/dist/gs/os/types.gs.js.map +1 -1
  93. package/dist/gs/os/types_js.gs.d.ts +2 -51
  94. package/dist/gs/os/types_js.gs.js +67 -105
  95. package/dist/gs/os/types_js.gs.js.map +1 -1
  96. package/dist/gs/os/types_unix.gs.js.map +1 -1
  97. package/dist/gs/path/filepath/match.js.map +1 -1
  98. package/dist/gs/path/match.js.map +1 -1
  99. package/dist/gs/path/path.js.map +1 -1
  100. package/dist/gs/reflect/index.d.ts +2 -2
  101. package/dist/gs/reflect/index.js +1 -1
  102. package/dist/gs/reflect/index.js.map +1 -1
  103. package/dist/gs/reflect/map.js.map +1 -1
  104. package/dist/gs/reflect/type.d.ts +2 -1
  105. package/dist/gs/reflect/type.js +85 -14
  106. package/dist/gs/reflect/type.js.map +1 -1
  107. package/dist/gs/reflect/types.js.map +1 -1
  108. package/dist/gs/reflect/visiblefields.js.map +1 -1
  109. package/dist/gs/runtime/runtime.js.map +1 -1
  110. package/dist/gs/sort/sort.gs.js.map +1 -1
  111. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  112. package/dist/gs/strconv/quote.gs.js.map +1 -1
  113. package/dist/gs/strings/builder.js.map +1 -1
  114. package/dist/gs/strings/reader.js.map +1 -1
  115. package/dist/gs/strings/replace.js.map +1 -1
  116. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  117. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  118. package/dist/gs/sync/sync.d.ts +1 -0
  119. package/dist/gs/sync/sync.js +12 -0
  120. package/dist/gs/sync/sync.js.map +1 -1
  121. package/dist/gs/time/time.js.map +1 -1
  122. package/dist/gs/unicode/unicode.js.map +1 -1
  123. package/go.mod +2 -2
  124. package/gs/builtin/builtin.ts +31 -6
  125. package/gs/builtin/hostio.test.ts +246 -0
  126. package/gs/builtin/hostio.ts +413 -0
  127. package/gs/builtin/index.ts +1 -0
  128. package/gs/builtin/print.test.ts +48 -0
  129. package/gs/builtin/print.ts +154 -0
  130. package/gs/builtin/runtime-contract.test.ts +230 -0
  131. package/gs/builtin/type.ts +84 -1
  132. package/gs/crypto/rand/index.test.ts +32 -0
  133. package/gs/crypto/rand/index.ts +90 -0
  134. package/gs/crypto/rand/meta.json +5 -0
  135. package/gs/encoding/json/index.test.ts +65 -0
  136. package/gs/encoding/json/index.ts +186 -0
  137. package/gs/fmt/fmt.test.ts +41 -30
  138. package/gs/fmt/fmt.ts +2 -22
  139. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +23 -0
  140. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +3 -1
  141. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/meta.json +3 -1
  142. package/gs/go/scanner/index.test.ts +50 -0
  143. package/gs/go/scanner/index.ts +157 -0
  144. package/gs/go/token/index.test.ts +21 -0
  145. package/gs/go/token/index.ts +120 -0
  146. package/gs/os/file_unix_js.test.ts +103 -0
  147. package/gs/os/meta.json +1 -2
  148. package/gs/os/tempfile.gs.test.ts +85 -0
  149. package/gs/os/tempfile.gs.ts +71 -11
  150. package/gs/os/types_js.gs.ts +74 -153
  151. package/gs/reflect/index.ts +1 -1
  152. package/gs/reflect/type.ts +106 -17
  153. package/gs/reflect/typefor.test.ts +75 -0
  154. package/gs/sync/sync.test.ts +24 -0
  155. package/gs/sync/sync.ts +12 -0
  156. package/package.json +13 -13
  157. package/compiler/analysis.go +0 -3475
  158. package/compiler/analysis_test.go +0 -338
  159. package/compiler/assignment.go +0 -580
  160. package/compiler/builtin_test.go +0 -92
  161. package/compiler/code-writer.go +0 -115
  162. package/compiler/compiler_test.go +0 -149
  163. package/compiler/composite-lit.go +0 -779
  164. package/compiler/config_test.go +0 -62
  165. package/compiler/constraint.go +0 -86
  166. package/compiler/decl.go +0 -801
  167. package/compiler/expr-call-async.go +0 -188
  168. package/compiler/expr-call-builtins.go +0 -208
  169. package/compiler/expr-call-helpers.go +0 -382
  170. package/compiler/expr-call-make.go +0 -318
  171. package/compiler/expr-call-type-conversion.go +0 -520
  172. package/compiler/expr-call.go +0 -413
  173. package/compiler/expr-selector.go +0 -343
  174. package/compiler/expr-star.go +0 -82
  175. package/compiler/expr-type.go +0 -442
  176. package/compiler/expr-value.go +0 -89
  177. package/compiler/expr.go +0 -773
  178. package/compiler/field.go +0 -183
  179. package/compiler/gs_dependencies_test.go +0 -298
  180. package/compiler/lit.go +0 -322
  181. package/compiler/output.go +0 -72
  182. package/compiler/primitive.go +0 -149
  183. package/compiler/protobuf.go +0 -697
  184. package/compiler/sanitize.go +0 -100
  185. package/compiler/spec-struct.go +0 -995
  186. package/compiler/spec-value.go +0 -540
  187. package/compiler/spec.go +0 -725
  188. package/compiler/stmt-assign.go +0 -664
  189. package/compiler/stmt-for.go +0 -266
  190. package/compiler/stmt-range.go +0 -475
  191. package/compiler/stmt-select.go +0 -262
  192. package/compiler/stmt-type-switch.go +0 -147
  193. package/compiler/stmt.go +0 -1308
  194. package/compiler/type-assert.go +0 -386
  195. package/compiler/type-info.go +0 -156
  196. package/compiler/type-utils.go +0 -207
  197. package/compiler/type.go +0 -892
@@ -1,475 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "fmt"
5
- "go/ast"
6
- "go/token"
7
- "go/types"
8
- "strings"
9
-
10
- "github.com/pkg/errors"
11
- )
12
-
13
- // WriteStmtRange translates a Go `for...range` statement (`ast.RangeStmt`)
14
- // into an equivalent TypeScript loop. The translation depends on the type of
15
- // the expression being ranged over (`exp.X`), determined using `go/types` info.
16
- //
17
- // - **Maps (`*types.Map`):**
18
- // `for k, v := range myMap` becomes `for (const [k_ts, v_ts] of myMap_ts.entries()) { const k = k_ts; const v = v_ts; ...body... }`.
19
- // If only `k` or `v` (or neither) is used, the corresponding TypeScript const declaration is adjusted.
20
- //
21
- // - **Strings (`*types.Basic` with `IsString` info):**
22
- // `for i, r := range myString` becomes:
23
- // `const _runes = $.stringToRunes(myString_ts);`
24
- // `for (let i_ts = 0; i_ts < _runes.length; i_ts++) { const r_ts = _runes[i_ts]; ...body... }`.
25
- // The index variable `i_ts` uses the Go key variable name if provided (and not `_`).
26
- // The rune variable `r_ts` uses the Go value variable name.
27
- //
28
- // - **Integers (`*types.Basic` with `IsInteger` info, Go 1.22+):**
29
- // `for i := range N` becomes `for (let i_ts = 0; i_ts < N_ts; i_ts++) { ...body... }`.
30
- // `for i, v := range N` becomes `for (let i_ts = 0; i_ts < N_ts; i_ts++) { const v_ts = i_ts; ...body... }`.
31
- //
32
- // - **Arrays (`*types.Array`) and Slices (`*types.Slice`):**
33
- // - If both key (index) and value are used (`for i, val := range arr`):
34
- // `for (let i_ts = 0; i_ts < arr_ts.length; i_ts++) { const val_ts = arr_ts[i_ts]; ...body... }`.
35
- // - If only the key (index) is used (`for i := range arr`):
36
- // `for (let i_ts = 0; i_ts < arr_ts.length; i_ts++) { ...body... }`.
37
- // - If only the value is used (`for _, val := range arr`):
38
- // `for (const v_ts of arr_ts) { const val_ts = v_ts; ...body... }`.
39
- // - If neither is used (e.g., `for range arr`), a simple index loop `for (let _i = 0; ...)` is generated.
40
- // The index variable `i_ts` uses the Go key variable name if provided.
41
- //
42
- // Loop variables (`exp.Key`, `exp.Value`) are declared as `const` inside the loop
43
- // body if they are not blank identifiers (`_`). The loop body (`exp.Body`) is
44
- // translated using `WriteStmtBlock` (or `WriteStmt` for array/slice with key and value).
45
- // If the ranged type is not supported, a comment is written, and an error is returned.
46
- func (c *GoToTSCompiler) WriteStmtRange(exp *ast.RangeStmt) error {
47
- // Get the type of the iterable expression
48
- iterType := c.pkg.TypesInfo.TypeOf(exp.X)
49
- underlying := iterType.Underlying()
50
-
51
- // Handle map types (both concrete maps and type parameters constrained to maps)
52
- if c.isMapType(iterType, underlying) {
53
- return c.writeMapRange(exp)
54
- }
55
-
56
- // Handle basic types (string, integer)
57
- if basic, ok := underlying.(*types.Basic); ok {
58
- if c.isStringType(iterType) {
59
- return c.writeStringRange(exp)
60
- } else if basic.Info()&types.IsInteger != 0 {
61
- return c.writeIntegerRange(exp)
62
- }
63
- }
64
-
65
- // Handle array and slice types
66
- if c.isArrayOrSlice(underlying) {
67
- return c.writeArraySliceRange(exp, false)
68
- }
69
-
70
- // Handle pointer to array/slice types
71
- if ptrType, ok := underlying.(*types.Pointer); ok {
72
- elem := ptrType.Elem().Underlying()
73
- if c.isArrayOrSlice(elem) {
74
- return c.writeArraySliceRange(exp, true)
75
- }
76
- }
77
-
78
- // Handle iterator function signatures
79
- if sig, ok := underlying.(*types.Signature); ok {
80
- if c.isIteratorSignature(sig) {
81
- return c.writeIteratorRange(exp, sig)
82
- }
83
- }
84
-
85
- // Handle interface types that may represent iterators
86
- if _, ok := underlying.(*types.Interface); ok {
87
- return c.writeInterfaceIteratorRange(exp)
88
- }
89
-
90
- if _, ok := underlying.(*types.Chan); ok {
91
- return c.writeChannelRange(exp)
92
- }
93
-
94
- return errors.Errorf("unsupported range loop type: %T for expression %v", underlying, exp)
95
- }
96
-
97
- // Helper functions
98
-
99
- func (c *GoToTSCompiler) isIteratorSignature(sig *types.Signature) bool {
100
- params := sig.Params()
101
- if params.Len() != 1 {
102
- return false
103
- }
104
- yieldParam := params.At(0).Type()
105
- if yieldSig, ok := yieldParam.Underlying().(*types.Signature); ok {
106
- yieldResults := yieldSig.Results()
107
- if yieldResults.Len() == 1 {
108
- if basic, ok := yieldResults.At(0).Type().Underlying().(*types.Basic); ok && basic.Kind() == types.Bool {
109
- return true
110
- }
111
- }
112
- }
113
- return false
114
- }
115
-
116
- func (c *GoToTSCompiler) getIndexVarName(exp *ast.RangeStmt, defaultName string) string {
117
- if exp.Key != nil {
118
- if keyIdent, ok := exp.Key.(*ast.Ident); ok && keyIdent.Name != "_" {
119
- return keyIdent.Name
120
- }
121
- }
122
- return defaultName
123
- }
124
-
125
- func (c *GoToTSCompiler) writeMapRange(exp *ast.RangeStmt) error {
126
- keyVarName := "_k"
127
- valueVarName := "_v"
128
-
129
- if exp.Key != nil {
130
- if ident, ok := exp.Key.(*ast.Ident); ok && ident.Name != "_" {
131
- keyVarName = ident.Name
132
- }
133
- }
134
- if exp.Value != nil {
135
- if ident, ok := exp.Value.(*ast.Ident); ok && ident.Name != "_" {
136
- valueVarName = ident.Name
137
- }
138
- }
139
-
140
- c.tsw.WriteLiterallyf("for (const [%s, %s] of ", keyVarName, valueVarName)
141
- if err := c.WriteValueExpr(exp.X); err != nil {
142
- return fmt.Errorf("failed to write range loop map expression: %w", err)
143
- }
144
- c.tsw.WriteLiterally("?.entries() ?? []) {")
145
- c.tsw.Indent(1)
146
- c.tsw.WriteLine("")
147
-
148
- if err := c.WriteStmtBlock(exp.Body, false); err != nil {
149
- return fmt.Errorf("failed to write range loop map body: %w", err)
150
- }
151
- c.tsw.Indent(-1)
152
- c.tsw.WriteLine("}")
153
- return nil
154
- }
155
-
156
- func (c *GoToTSCompiler) writeStringRange(exp *ast.RangeStmt) error {
157
- c.tsw.WriteLine("{")
158
- c.tsw.Indent(1)
159
-
160
- c.tsw.WriteLiterally("const _runes = $.stringToRunes(")
161
- if err := c.WriteValueExpr(exp.X); err != nil {
162
- return fmt.Errorf("failed to write range loop string conversion expression: %w", err)
163
- }
164
- c.tsw.WriteLiterally(")")
165
- c.tsw.WriteLine("")
166
-
167
- indexVarName := c.getIndexVarName(exp, "i")
168
- c.tsw.WriteLiterallyf("for (let %s = 0; %s < _runes.length; %s++) {", indexVarName, indexVarName, indexVarName)
169
- c.tsw.Indent(1)
170
- c.tsw.WriteLine("")
171
-
172
- if exp.Value != nil {
173
- if ident, ok := exp.Value.(*ast.Ident); ok && ident.Name != "_" {
174
- c.tsw.WriteLiterally("let ")
175
- c.WriteIdent(ident, false)
176
- c.tsw.WriteLiterally(" = _runes[")
177
- c.tsw.WriteLiterally(indexVarName)
178
- c.tsw.WriteLiterally("]")
179
- c.tsw.WriteLine("")
180
- }
181
- }
182
-
183
- if err := c.WriteStmtBlock(exp.Body, false); err != nil {
184
- return fmt.Errorf("failed to write range loop string body: %w", err)
185
- }
186
- c.tsw.Indent(-1)
187
- c.tsw.WriteLine("}")
188
- c.tsw.Indent(-1)
189
- c.tsw.WriteLine("}")
190
- return nil
191
- }
192
-
193
- func (c *GoToTSCompiler) writeIntegerRange(exp *ast.RangeStmt) error {
194
- if exp.Value != nil {
195
- return errors.Errorf("ranging over an integer supports key variable only (not value variable): %v", exp)
196
- }
197
-
198
- indexVarName := c.getIndexVarName(exp, "_i")
199
- c.tsw.WriteLiterallyf("for (let %s = 0; %s < ", indexVarName, indexVarName)
200
- if err := c.WriteValueExpr(exp.X); err != nil {
201
- return fmt.Errorf("failed to write range loop integer expression: %w", err)
202
- }
203
- c.tsw.WriteLiterallyf("; %s++) {", indexVarName)
204
-
205
- if err := c.WriteStmtBlock(exp.Body, false); err != nil {
206
- return fmt.Errorf("failed to write range loop integer body: %w", err)
207
- }
208
-
209
- c.tsw.Indent(-1)
210
- c.tsw.WriteLine("}")
211
- return nil
212
- }
213
-
214
- func (c *GoToTSCompiler) writeArraySliceRange(exp *ast.RangeStmt, isPointer bool) error {
215
- indexVarName := c.getIndexVarName(exp, "_i")
216
-
217
- // Handle the different cases
218
- if exp.Key != nil && exp.Value != nil {
219
- return c.writeArraySliceWithKeyValue(exp, indexVarName, isPointer)
220
- } else if exp.Key != nil && exp.Value == nil {
221
- return c.writeArraySliceKeyOnly(exp, indexVarName, isPointer)
222
- } else if exp.Key == nil && exp.Value != nil {
223
- return errors.Errorf("unexpected value without key in for range expression: %v", exp)
224
- } else {
225
- return c.writeArraySliceFallback(exp, isPointer)
226
- }
227
- }
228
-
229
- func (c *GoToTSCompiler) writeArraySliceWithKeyValue(exp *ast.RangeStmt, indexVarName string, isPointer bool) error {
230
- c.tsw.WriteLiterallyf("for (let %s = 0; %s < $.len(", indexVarName, indexVarName)
231
- if err := c.writeArraySliceExpression(exp.X, isPointer); err != nil {
232
- return fmt.Errorf("failed to write range loop array/slice expression (key and value): %w", err)
233
- }
234
- c.tsw.WriteLiterallyf("); %s++) {", indexVarName)
235
- c.tsw.Indent(1)
236
- c.tsw.WriteLine("")
237
-
238
- if ident, ok := exp.Value.(*ast.Ident); ok && ident.Name != "_" {
239
- c.tsw.WriteLiterally("let ")
240
- c.WriteIdent(ident, false)
241
- c.tsw.WriteLiterally(" = ")
242
- if err := c.writeArraySliceExpression(exp.X, isPointer); err != nil {
243
- return fmt.Errorf("failed to write range loop array/slice value expression: %w", err)
244
- }
245
- c.tsw.WriteLiterallyf("![%s]", indexVarName)
246
- c.tsw.WriteLine("")
247
- }
248
-
249
- if err := c.WriteStmt(exp.Body); err != nil {
250
- return fmt.Errorf("failed to write range loop array/slice body (key and value): %w", err)
251
- }
252
- c.tsw.Indent(-1)
253
- c.tsw.WriteLine("}")
254
- return nil
255
- }
256
-
257
- func (c *GoToTSCompiler) writeArraySliceKeyOnly(exp *ast.RangeStmt, indexVarName string, isPointer bool) error {
258
- c.tsw.WriteLiterallyf("for (let %s = 0; %s < $.len(", indexVarName, indexVarName)
259
- if err := c.writeArraySliceExpression(exp.X, isPointer); err != nil {
260
- return fmt.Errorf("failed to write expression for the iterable: %w", err)
261
- }
262
- c.tsw.WriteLiterallyf("); %s++) {", indexVarName)
263
- c.tsw.Indent(1)
264
- c.tsw.WriteLine("")
265
-
266
- if err := c.WriteStmtBlock(exp.Body, false); err != nil {
267
- return fmt.Errorf("failed to write range loop array/slice body (only key): %w", err)
268
- }
269
- c.tsw.Indent(-1)
270
- c.tsw.WriteLine("}")
271
- return nil
272
- }
273
-
274
- func (c *GoToTSCompiler) writeArraySliceFallback(exp *ast.RangeStmt, isPointer bool) error {
275
- indexVarName := "_i"
276
- c.tsw.WriteLiterallyf("for (let %s = 0; %s < $.len(", indexVarName, indexVarName)
277
- if err := c.writeArraySliceExpression(exp.X, isPointer); err != nil {
278
- return fmt.Errorf("failed to write range loop array/slice length expression (fallback): %w", err)
279
- }
280
- c.tsw.WriteLiterallyf("); %s++) {", indexVarName)
281
- c.tsw.Indent(1)
282
- c.tsw.WriteLine("")
283
-
284
- if err := c.WriteStmtBlock(exp.Body, false); err != nil {
285
- return fmt.Errorf("failed to write range loop array/slice body (fallback): %w", err)
286
- }
287
- c.tsw.Indent(-1)
288
- c.tsw.WriteLine("}")
289
- return nil
290
- }
291
-
292
- func (c *GoToTSCompiler) writeArraySliceExpression(expr ast.Expr, isPointer bool) error {
293
- if isPointer {
294
- if ident, ok := expr.(*ast.Ident); ok {
295
- c.WriteIdent(ident, false)
296
- } else {
297
- if err := c.WriteValueExpr(expr); err != nil {
298
- return err
299
- }
300
- }
301
- c.tsw.WriteLiterally("!.value")
302
- return nil
303
- } else {
304
- return c.WriteValueExpr(expr)
305
- }
306
- }
307
-
308
- func (c *GoToTSCompiler) writeIteratorRange(exp *ast.RangeStmt, sig *types.Signature) error {
309
- params := sig.Params()
310
- yieldParam := params.At(0).Type()
311
- yieldSig := yieldParam.Underlying().(*types.Signature)
312
- yieldParams := yieldSig.Params()
313
-
314
- c.tsw.WriteLiterally(";(() => {")
315
- c.tsw.Indent(1)
316
- c.tsw.WriteLine("")
317
- c.tsw.WriteLiterally("let shouldContinue = true")
318
- c.tsw.WriteLine("")
319
-
320
- if err := c.WriteValueExpr(exp.X); err != nil {
321
- return fmt.Errorf("failed to write iterator expression: %w", err)
322
- }
323
-
324
- switch yieldParams.Len() {
325
- case 0:
326
- c.tsw.WriteLiterally("!(() => {")
327
- case 1:
328
- c.tsw.WriteLiterally("!((")
329
- c.writeIteratorParam(exp.Value, "v")
330
- c.tsw.WriteLiterally(") => {")
331
- case 2:
332
- c.tsw.WriteLiterally("!((")
333
- c.writeIteratorParam(exp.Key, "k")
334
- c.tsw.WriteLiterally(", ")
335
- c.writeIteratorParam(exp.Value, "v")
336
- c.tsw.WriteLiterally(") => {")
337
- }
338
-
339
- c.tsw.Indent(1)
340
- c.tsw.WriteLine("")
341
- if err := c.WriteStmtBlock(exp.Body, false); err != nil {
342
- return fmt.Errorf("failed to write iterator body: %w", err)
343
- }
344
- c.tsw.WriteLiterally("return shouldContinue")
345
- c.tsw.WriteLine("")
346
- c.tsw.Indent(-1)
347
- c.tsw.WriteLiterally("})")
348
- c.tsw.WriteLine("")
349
- c.tsw.Indent(-1)
350
- c.tsw.WriteLine("})()")
351
- return nil
352
- }
353
-
354
- func (c *GoToTSCompiler) writeIteratorParam(param ast.Expr, defaultName string) {
355
- if param != nil {
356
- if ident, ok := param.(*ast.Ident); ok && ident.Name != "_" {
357
- c.WriteIdent(ident, false)
358
- return
359
- }
360
- }
361
- c.tsw.WriteLiterally(defaultName)
362
- }
363
-
364
- func (c *GoToTSCompiler) writeInterfaceIteratorRange(exp *ast.RangeStmt) error {
365
- c.tsw.WriteLiterally(";(() => {")
366
- c.tsw.Indent(1)
367
- c.tsw.WriteLine("")
368
- c.tsw.WriteLiterally("let shouldContinue = true")
369
- c.tsw.WriteLine("")
370
-
371
- if err := c.WriteValueExpr(exp.X); err != nil {
372
- return fmt.Errorf("failed to write interface iterator expression: %w", err)
373
- }
374
-
375
- if exp.Key != nil && exp.Value != nil {
376
- c.tsw.WriteLiterally("!((")
377
- c.writeIteratorParam(exp.Key, "k")
378
- c.tsw.WriteLiterally(", ")
379
- c.writeIteratorParam(exp.Value, "v")
380
- c.tsw.WriteLiterally(") => {")
381
- } else if exp.Value != nil {
382
- c.tsw.WriteLiterally("!((")
383
- c.writeIteratorParam(exp.Value, "v")
384
- c.tsw.WriteLiterally(") => {")
385
- } else if exp.Key != nil {
386
- c.tsw.WriteLiterally("!((")
387
- c.writeIteratorParam(exp.Key, "k")
388
- c.tsw.WriteLiterally(") => {")
389
- } else {
390
- c.tsw.WriteLiterally("!(() => {")
391
- }
392
-
393
- c.tsw.Indent(1)
394
- c.tsw.WriteLine("")
395
- if err := c.WriteStmtBlock(exp.Body, false); err != nil {
396
- return fmt.Errorf("failed to write interface iterator body: %w", err)
397
- }
398
- c.tsw.WriteLiterally("return shouldContinue")
399
- c.tsw.WriteLine("")
400
- c.tsw.Indent(-1)
401
- c.tsw.WriteLiterally("})")
402
- c.tsw.WriteLine("")
403
- c.tsw.Indent(-1)
404
- c.tsw.WriteLine("})()")
405
- return nil
406
- }
407
-
408
- func (c *GoToTSCompiler) writeChannelRange(exp *ast.RangeStmt) error {
409
- if exp.Value != nil {
410
- return fmt.Errorf("channel range does not support two iteration variables")
411
- }
412
-
413
- c.tsw.WriteLiterally("for (;;) {")
414
- c.tsw.Indent(1)
415
- c.tsw.WriteLine("")
416
-
417
- valueIsBlank := exp.Key == nil
418
- valueName := "_"
419
- if !valueIsBlank {
420
- if valIdent, ok := exp.Key.(*ast.Ident); ok {
421
- if valIdent.Name != "_" {
422
- valueName = valIdent.Name
423
- } else {
424
- valueIsBlank = true
425
- }
426
- } else {
427
- return fmt.Errorf("unsupported iteration variable in channel range: %T", exp.Key)
428
- }
429
- }
430
-
431
- keyword := "const "
432
- okVarName := "_ok"
433
- if exp.Tok != token.DEFINE {
434
- keyword = ""
435
- c.tsw.WriteLiterally("let ")
436
- c.tsw.WriteLiterally(okVarName)
437
- c.tsw.WriteLine("")
438
- }
439
-
440
- patternParts := []string{}
441
- if !valueIsBlank {
442
- patternParts = append(patternParts, fmt.Sprintf("value: %s", valueName))
443
- }
444
- patternParts = append(patternParts, fmt.Sprintf("ok: %s", okVarName))
445
- destructuringPattern := fmt.Sprintf("{ %s }", strings.Join(patternParts, ", "))
446
-
447
- c.tsw.WriteLiterally(keyword)
448
- if keyword == "" {
449
- c.tsw.WriteLiterally(";(")
450
- }
451
- c.tsw.WriteLiterally(destructuringPattern)
452
- c.tsw.WriteLiterally(" = await $.chanRecvWithOk(")
453
- if err := c.WriteValueExpr(exp.X); err != nil {
454
- return err
455
- }
456
- c.tsw.WriteLiterally(")")
457
- if keyword == "" {
458
- c.tsw.WriteLiterally(")")
459
- }
460
- c.tsw.WriteLine("")
461
-
462
- c.tsw.WriteLiterally("if (!")
463
- c.tsw.WriteLiterally(okVarName)
464
- c.tsw.WriteLiterally(") break")
465
- c.tsw.WriteLine("")
466
-
467
- if err := c.WriteStmtBlock(exp.Body, false); err != nil {
468
- return err
469
- }
470
-
471
- c.tsw.Indent(-1)
472
- c.tsw.WriteLine("}")
473
-
474
- return nil
475
- }