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.
- package/README.md +13 -1
- package/cmd/goscript/cmd_compile.go +70 -69
- package/cmd/goscript/cmd_compile_test.go +79 -0
- package/cmd/goscript/main.go +10 -5
- package/compiler/compile-request.go +218 -0
- package/compiler/compiler.go +16 -1336
- package/compiler/compliance_test.go +196 -0
- package/compiler/config.go +6 -13
- package/compiler/diagnostic.go +70 -0
- package/compiler/index.test.ts +28 -28
- package/compiler/index.ts +40 -72
- package/compiler/lowered-program.go +132 -0
- package/compiler/lowering.go +3576 -0
- package/compiler/override-registry.go +422 -0
- package/compiler/override-registry_test.go +207 -0
- package/compiler/package-graph.go +231 -0
- package/compiler/package-graph_test.go +281 -0
- package/compiler/result.go +13 -0
- package/compiler/runtime-contract.go +279 -0
- package/compiler/runtime-contract_test.go +90 -0
- package/compiler/semantic-model-types.go +110 -0
- package/compiler/semantic-model.go +922 -0
- package/compiler/semantic-model_test.go +416 -0
- package/compiler/service.go +133 -0
- package/compiler/skeleton_test.go +1145 -0
- package/compiler/typescript-emitter.go +663 -0
- package/compiler/wasm/compile.go +2 -3
- package/compiler/wasm/compile_test.go +29 -0
- package/compiler/wasm_api.go +10 -159
- package/dist/compiler/index.d.ts +1 -3
- package/dist/compiler/index.js +31 -55
- package/dist/compiler/index.js.map +1 -1
- package/dist/gs/builtin/builtin.d.ts +13 -0
- package/dist/gs/builtin/builtin.js +27 -7
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +3 -3
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +86 -0
- package/dist/gs/builtin/hostio.js +266 -0
- package/dist/gs/builtin/hostio.js.map +1 -0
- package/dist/gs/builtin/index.d.ts +1 -0
- package/dist/gs/builtin/index.js +1 -0
- package/dist/gs/builtin/index.js.map +1 -1
- package/dist/gs/builtin/print.d.ts +8 -0
- package/dist/gs/builtin/print.js +111 -0
- package/dist/gs/builtin/print.js.map +1 -0
- package/dist/gs/builtin/slice.d.ts +1 -1
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +11 -0
- package/dist/gs/builtin/type.js +55 -1
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/bytes.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/rand/index.d.ts +5 -0
- package/dist/gs/crypto/rand/index.js +77 -0
- package/dist/gs/crypto/rand/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +3 -0
- package/dist/gs/encoding/json/index.js +160 -0
- package/dist/gs/encoding/json/index.js.map +1 -0
- package/dist/gs/fmt/fmt.js +2 -22
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +29 -0
- package/dist/gs/go/scanner/index.js +120 -0
- package/dist/gs/go/scanner/index.js.map +1 -0
- package/dist/gs/go/token/index.d.ts +31 -0
- package/dist/gs/go/token/index.js +82 -0
- package/dist/gs/go/token/index.js.map +1 -0
- package/dist/gs/internal/abi/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/readfile.js.map +1 -1
- package/dist/gs/io/fs/stat.js.map +1 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +2 -4
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/rawconn_js.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/tempfile.gs.js +66 -9
- package/dist/gs/os/tempfile.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +2 -51
- package/dist/gs/os/types_js.gs.js +67 -105
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/match.js.map +1 -1
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +2 -2
- package/dist/gs/reflect/index.js +1 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +2 -1
- package/dist/gs/reflect/type.js +85 -14
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/sort/sort.gs.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/quote.gs.js.map +1 -1
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +1 -0
- package/dist/gs/sync/sync.js +12 -0
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/go.mod +2 -2
- package/gs/builtin/builtin.ts +31 -6
- package/gs/builtin/hostio.test.ts +246 -0
- package/gs/builtin/hostio.ts +413 -0
- package/gs/builtin/index.ts +1 -0
- package/gs/builtin/print.test.ts +48 -0
- package/gs/builtin/print.ts +154 -0
- package/gs/builtin/runtime-contract.test.ts +230 -0
- package/gs/builtin/type.ts +84 -1
- package/gs/crypto/rand/index.test.ts +32 -0
- package/gs/crypto/rand/index.ts +90 -0
- package/gs/crypto/rand/meta.json +5 -0
- package/gs/encoding/json/index.test.ts +65 -0
- package/gs/encoding/json/index.ts +186 -0
- package/gs/fmt/fmt.test.ts +41 -30
- package/gs/fmt/fmt.ts +2 -22
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +23 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +3 -1
- package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/meta.json +3 -1
- package/gs/go/scanner/index.test.ts +50 -0
- package/gs/go/scanner/index.ts +157 -0
- package/gs/go/token/index.test.ts +21 -0
- package/gs/go/token/index.ts +120 -0
- package/gs/os/file_unix_js.test.ts +103 -0
- package/gs/os/meta.json +1 -2
- package/gs/os/tempfile.gs.test.ts +85 -0
- package/gs/os/tempfile.gs.ts +71 -11
- package/gs/os/types_js.gs.ts +74 -153
- package/gs/reflect/index.ts +1 -1
- package/gs/reflect/type.ts +106 -17
- package/gs/reflect/typefor.test.ts +75 -0
- package/gs/sync/sync.test.ts +24 -0
- package/gs/sync/sync.ts +12 -0
- package/package.json +13 -13
- package/compiler/analysis.go +0 -3475
- package/compiler/analysis_test.go +0 -338
- package/compiler/assignment.go +0 -580
- package/compiler/builtin_test.go +0 -92
- package/compiler/code-writer.go +0 -115
- package/compiler/compiler_test.go +0 -149
- package/compiler/composite-lit.go +0 -779
- package/compiler/config_test.go +0 -62
- package/compiler/constraint.go +0 -86
- package/compiler/decl.go +0 -801
- package/compiler/expr-call-async.go +0 -188
- package/compiler/expr-call-builtins.go +0 -208
- package/compiler/expr-call-helpers.go +0 -382
- package/compiler/expr-call-make.go +0 -318
- package/compiler/expr-call-type-conversion.go +0 -520
- package/compiler/expr-call.go +0 -413
- package/compiler/expr-selector.go +0 -343
- package/compiler/expr-star.go +0 -82
- package/compiler/expr-type.go +0 -442
- package/compiler/expr-value.go +0 -89
- package/compiler/expr.go +0 -773
- package/compiler/field.go +0 -183
- package/compiler/gs_dependencies_test.go +0 -298
- package/compiler/lit.go +0 -322
- package/compiler/output.go +0 -72
- package/compiler/primitive.go +0 -149
- package/compiler/protobuf.go +0 -697
- package/compiler/sanitize.go +0 -100
- package/compiler/spec-struct.go +0 -995
- package/compiler/spec-value.go +0 -540
- package/compiler/spec.go +0 -725
- package/compiler/stmt-assign.go +0 -664
- package/compiler/stmt-for.go +0 -266
- package/compiler/stmt-range.go +0 -475
- package/compiler/stmt-select.go +0 -262
- package/compiler/stmt-type-switch.go +0 -147
- package/compiler/stmt.go +0 -1308
- package/compiler/type-assert.go +0 -386
- package/compiler/type-info.go +0 -156
- package/compiler/type-utils.go +0 -207
- package/compiler/type.go +0 -892
package/compiler/stmt-range.go
DELETED
|
@@ -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
|
-
}
|