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,382 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "go/ast"
5
- "go/types"
6
-
7
- "github.com/pkg/errors"
8
- )
9
-
10
- // writeByteSliceCreation handles the creation of []byte slices with proper Uint8Array handling
11
- func (c *GoToTSCompiler) writeByteSliceCreation(lengthArg, capacityArg any) error {
12
- return c.writeSliceCreationForType(lengthArg, capacityArg, true)
13
- }
14
-
15
- // writeSliceCreationForType handles slice creation with special handling for byte slices
16
- func (c *GoToTSCompiler) writeSliceCreationForType(lengthArg, capacityArg any, isByteSlice bool) error {
17
- hasCapacity := capacityArg != nil
18
-
19
- if isByteSlice && !hasCapacity {
20
- // make([]byte, len) - capacity equals length, use Uint8Array
21
- c.tsw.WriteLiterally("new Uint8Array(")
22
- if err := c.writeExprOrDefault(lengthArg, "0"); err != nil {
23
- return err
24
- }
25
- c.tsw.WriteLiterally(")")
26
- return nil
27
- }
28
-
29
- // Use $.makeSlice for all other cases
30
- if isByteSlice {
31
- c.tsw.WriteLiterally("$.makeSlice<number>(")
32
- } else {
33
- return errors.New("writeSliceCreationForType called for non-byte slice without element type")
34
- }
35
-
36
- if err := c.writeExprOrDefault(lengthArg, "0"); err != nil {
37
- return err
38
- }
39
-
40
- if hasCapacity {
41
- c.tsw.WriteLiterally(", ")
42
- if err := c.writeExprOrDefault(capacityArg, "0"); err != nil {
43
- return err
44
- }
45
- }
46
-
47
- if isByteSlice {
48
- c.tsw.WriteLiterally(", 'byte')")
49
- }
50
-
51
- return nil
52
- }
53
-
54
- // writeGenericSliceCreation handles the creation of generic slices with proper type hints
55
- func (c *GoToTSCompiler) writeGenericSliceCreation(elemType types.Type, lengthArg, capacityArg any) error {
56
- hasCapacity := capacityArg != nil
57
-
58
- c.tsw.WriteLiterally("$.makeSlice<")
59
- c.WriteGoType(elemType, GoTypeContextGeneral)
60
- c.tsw.WriteLiterally(">(")
61
-
62
- if err := c.writeExprOrDefault(lengthArg, "0"); err != nil {
63
- return err
64
- }
65
-
66
- if hasCapacity {
67
- c.tsw.WriteLiterally(", ")
68
- if err := c.writeExprOrDefault(capacityArg, "0"); err != nil {
69
- return err
70
- }
71
- }
72
-
73
- // Add type hint for proper zero value initialization
74
- c.writeSliceTypeHint(elemType, hasCapacity)
75
- c.tsw.WriteLiterally(")")
76
- return nil
77
- }
78
-
79
- // writeSliceTypeHint writes the type hint parameter for makeSlice calls
80
- func (c *GoToTSCompiler) writeSliceTypeHint(elemType types.Type, hasCapacity bool) {
81
- typeHint := c.getTypeHintForSliceElement(elemType)
82
- if typeHint != "" {
83
- if !hasCapacity {
84
- c.tsw.WriteLiterally(", undefined")
85
- }
86
- c.tsw.WriteLiterally(", '")
87
- c.tsw.WriteLiterally(typeHint)
88
- c.tsw.WriteLiterally("'")
89
- }
90
- }
91
-
92
- // writeExprOrDefault writes an expression if it's not nil, otherwise writes a default value
93
- func (c *GoToTSCompiler) writeExprOrDefault(expr any, defaultValue string) error {
94
- if expr == nil {
95
- c.tsw.WriteLiterally(defaultValue)
96
- return nil
97
- }
98
-
99
- switch e := expr.(type) {
100
- case string:
101
- c.tsw.WriteLiterally(e)
102
- return nil
103
- case ast.Expr:
104
- // If it's an ast.Expr, call WriteValueExpr directly
105
- return c.WriteValueExpr(e)
106
- default:
107
- // If we can't handle the type, return an error
108
- return errors.Errorf("unsupported expression type in writeExprOrDefault: %T", e)
109
- }
110
- }
111
-
112
- // writeReflectTypeFor handles reflect.TypeFor[T]() calls by generating appropriate TypeScript
113
- func (c *GoToTSCompiler) writeReflectTypeFor(exp *ast.CallExpr, selectorExpr *ast.SelectorExpr) (handled bool, err error) {
114
- // Check if this is reflect.TypeFor
115
- if selectorExpr.Sel.Name != "TypeFor" {
116
- return false, nil
117
- }
118
-
119
- // Check if X is an identifier referring to the reflect package
120
- xIdent, ok := selectorExpr.X.(*ast.Ident)
121
- if !ok {
122
- return false, nil
123
- }
124
-
125
- obj := c.objectOfIdent(xIdent)
126
- if obj == nil {
127
- return false, nil
128
- }
129
-
130
- pkgName, ok := obj.(*types.PkgName)
131
- if !ok || pkgName.Imported().Path() != "reflect" {
132
- return false, nil
133
- }
134
-
135
- // DEBUG: We found reflect.TypeFor
136
- // fmt.Printf("DEBUG: Found reflect.TypeFor call\n")
137
-
138
- // This is reflect.TypeFor - now get the type argument
139
- if c.pkg.TypesInfo.Instances == nil {
140
- return false, errors.New("reflect.TypeFor called but no type instances available")
141
- }
142
-
143
- instance, hasInstance := c.pkg.TypesInfo.Instances[selectorExpr.Sel]
144
- if !hasInstance || instance.TypeArgs == nil || instance.TypeArgs.Len() == 0 {
145
- return false, errors.New("reflect.TypeFor called without type arguments")
146
- }
147
-
148
- // Get the first type argument
149
- typeArg := instance.TypeArgs.At(0)
150
- // fmt.Printf("DEBUG: Type argument: %v\n", typeArg)
151
-
152
- if named, ok := typeArg.(*types.Named); ok {
153
- if _, isInterface := named.Underlying().(*types.Interface); isInterface {
154
- typeName := qualifiedTypeName(named)
155
- c.tsw.WriteLiterally("reflect.getInterfaceLiteralTypeByName(\"" + typeName + "\")")
156
- return true, nil
157
- }
158
- }
159
-
160
- // Generate TypeScript code to create a Type for this type
161
- if err := c.writeTypeForTypeArg(typeArg); err != nil {
162
- return true, err
163
- }
164
-
165
- return true, nil
166
- }
167
-
168
- // writeReflectTypeAssert handles reflect.TypeAssert[T](v) calls.
169
- func (c *GoToTSCompiler) writeReflectTypeAssert(exp *ast.CallExpr, selectorExpr *ast.SelectorExpr) (handled bool, err error) {
170
- if selectorExpr.Sel.Name != "TypeAssert" {
171
- return false, nil
172
- }
173
-
174
- xIdent, ok := selectorExpr.X.(*ast.Ident)
175
- if !ok {
176
- return false, nil
177
- }
178
-
179
- obj := c.objectOfIdent(xIdent)
180
- if obj == nil {
181
- return false, nil
182
- }
183
-
184
- pkgName, ok := obj.(*types.PkgName)
185
- if !ok || pkgName.Imported().Path() != "reflect" {
186
- return false, nil
187
- }
188
-
189
- if len(exp.Args) != 1 {
190
- return false, errors.New("reflect.TypeAssert called with unexpected argument count")
191
- }
192
-
193
- if c.pkg.TypesInfo.Instances == nil {
194
- return false, errors.New("reflect.TypeAssert called but no type instances available")
195
- }
196
-
197
- instance, hasInstance := c.pkg.TypesInfo.Instances[selectorExpr.Sel]
198
- if !hasInstance || instance.TypeArgs == nil || instance.TypeArgs.Len() == 0 {
199
- return false, errors.New("reflect.TypeAssert called without type arguments")
200
- }
201
-
202
- typeArg := instance.TypeArgs.At(0)
203
-
204
- c.tsw.WriteLiterally("$.typeAssertTuple<")
205
- c.WriteGoType(typeArg, GoTypeContextGeneral)
206
- c.tsw.WriteLiterally(">(")
207
- if err := c.WriteValueExpr(exp.Args[0]); err != nil {
208
- return true, err
209
- }
210
- c.tsw.WriteLiterally(".Interface(), ")
211
- c.writeTypeInfoObject(typeArg)
212
- c.tsw.WriteLiterally(")")
213
- return true, nil
214
- }
215
-
216
- // writeTypeForTypeArg generates TypeScript code to create a reflect.Type for the given Go type
217
- func (c *GoToTSCompiler) writeTypeForTypeArg(t types.Type) error {
218
- // Handle basic types
219
- switch underlying := t.Underlying().(type) {
220
- case *types.Basic:
221
- return c.writeBasicTypeFor(underlying)
222
- case *types.Named:
223
- // For named types, use TypeOf with a zero value
224
- return c.writeNamedTypeFor(t)
225
- case *types.Pointer:
226
- // For pointer types, use PointerTo
227
- c.tsw.WriteLiterally("reflect.PointerTo(")
228
- if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
229
- return err
230
- }
231
- c.tsw.WriteLiterally(")")
232
- return nil
233
- case *types.Slice:
234
- c.tsw.WriteLiterally("reflect.SliceOf(")
235
- if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
236
- return err
237
- }
238
- c.tsw.WriteLiterally(")")
239
- return nil
240
- case *types.Array:
241
- c.tsw.WriteLiterally("reflect.ArrayOf(")
242
- c.tsw.WriteLiterallyf("%d, ", underlying.Len())
243
- if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
244
- return err
245
- }
246
- c.tsw.WriteLiterally(")")
247
- return nil
248
- case *types.Map:
249
- c.tsw.WriteLiterally("reflect.MapOf(")
250
- if err := c.writeTypeForTypeArg(underlying.Key()); err != nil {
251
- return err
252
- }
253
- c.tsw.WriteLiterally(", ")
254
- if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
255
- return err
256
- }
257
- c.tsw.WriteLiterally(")")
258
- return nil
259
- case *types.Chan:
260
- c.tsw.WriteLiterally("reflect.ChanOf(")
261
- switch underlying.Dir() {
262
- case types.RecvOnly:
263
- c.tsw.WriteLiterally("reflect.RecvDir")
264
- case types.SendOnly:
265
- c.tsw.WriteLiterally("reflect.SendDir")
266
- default:
267
- c.tsw.WriteLiterally("reflect.BothDir")
268
- }
269
- c.tsw.WriteLiterally(", ")
270
- if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
271
- return err
272
- }
273
- c.tsw.WriteLiterally(")")
274
- return nil
275
- case *types.Struct:
276
- // For struct types, use TypeOf with zero value
277
- return c.writeNamedTypeFor(t)
278
- case *types.Interface:
279
- // For interface types, use TypeOf with null
280
- return c.writeNamedTypeFor(t)
281
- default:
282
- return errors.Errorf("unsupported type for reflect.TypeFor: %T", underlying)
283
- }
284
- }
285
-
286
- // writeBasicTypeFor generates code for basic types
287
- func (c *GoToTSCompiler) writeBasicTypeFor(basic *types.Basic) error {
288
- // Map basic types to their reflect constructors or TypeOf calls
289
- // Note: We don't pass type parameters to TypeOf - it infers from the value
290
- switch basic.Kind() {
291
- case types.Bool:
292
- c.tsw.WriteLiterally("reflect.TypeOf(false)")
293
- case types.Int:
294
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
295
- case types.Int8:
296
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
297
- case types.Int16:
298
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
299
- case types.Int32:
300
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
301
- case types.Int64:
302
- c.tsw.WriteLiterally("reflect.TypeOf(0n)")
303
- case types.Uint:
304
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
305
- case types.Uint8:
306
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
307
- case types.Uint16:
308
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
309
- case types.Uint32:
310
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
311
- case types.Uint64:
312
- c.tsw.WriteLiterally("reflect.TypeOf(0n)")
313
- case types.Uintptr:
314
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
315
- case types.Float32:
316
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
317
- case types.Float64:
318
- c.tsw.WriteLiterally("reflect.TypeOf(0)")
319
- case types.Complex64:
320
- c.tsw.WriteLiterally("reflect.TypeOf([0, 0])")
321
- case types.Complex128:
322
- c.tsw.WriteLiterally("reflect.TypeOf([0, 0])")
323
- case types.String:
324
- c.tsw.WriteLiterally("reflect.TypeOf(\"\")")
325
- case types.UnsafePointer:
326
- c.tsw.WriteLiterally("reflect.TypeOf(null)")
327
- default:
328
- return errors.Errorf("unsupported basic type for reflect.TypeFor: %v", basic)
329
- }
330
- return nil
331
- }
332
-
333
- // writeNamedTypeFor generates code for named types (structs, interfaces, etc.)
334
- func (c *GoToTSCompiler) writeNamedTypeFor(t types.Type) error {
335
- // For interface types, we need special handling since null doesn't carry type info
336
- if _, ok := t.Underlying().(*types.Interface); ok {
337
- if named, ok := t.(*types.Named); ok {
338
- obj := named.Obj()
339
- pkgPath := ""
340
- if pkg := obj.Pkg(); pkg != nil {
341
- if pkg.Name() == "main" {
342
- pkgPath = "main."
343
- } else if pkg.Path() != "" {
344
- pkgPath = pkg.Path() + "."
345
- }
346
- }
347
- typeName := pkgPath + obj.Name()
348
- c.tsw.WriteLiterally("reflect.getInterfaceTypeByName(\"" + typeName + "\")")
349
- return nil
350
- }
351
- // For anonymous interfaces, use TypeOf(null)
352
- c.tsw.WriteLiterally("reflect.TypeOf(null)")
353
- return nil
354
- }
355
-
356
- // For named types, we need to create a zero value and call TypeOf
357
- // Note: We don't pass a type parameter to TypeOf - it infers the type from the value
358
- c.tsw.WriteLiterally("reflect.TypeOf(")
359
-
360
- // Generate a zero value for this type
361
- switch underlying := t.Underlying().(type) {
362
- case *types.Struct:
363
- // For struct types: new MyStruct()
364
- // Check if this is a named type
365
- if _, ok := t.(*types.Named); ok {
366
- c.tsw.WriteLiterally("new ")
367
- c.WriteGoType(t, GoTypeContextGeneral)
368
- c.tsw.WriteLiterally("()")
369
- } else {
370
- // Anonymous struct
371
- c.tsw.WriteLiterally("{}")
372
- }
373
- case *types.Basic:
374
- // For basic types wrapped in named types
375
- return c.writeBasicTypeFor(underlying)
376
- default:
377
- return errors.Errorf("unsupported named type underlying for reflect.TypeFor: %T", underlying)
378
- }
379
-
380
- c.tsw.WriteLiterally(")")
381
- return nil
382
- }
@@ -1,318 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "fmt"
5
- "go/ast"
6
- "go/types"
7
-
8
- "github.com/pkg/errors"
9
- )
10
-
11
- // getTypeHintForSliceElement returns the appropriate type hint for makeSlice based on the Go element type
12
- func (c *GoToTSCompiler) getTypeHintForSliceElement(elemType types.Type) string {
13
- if basicType, isBasic := elemType.(*types.Basic); isBasic {
14
- switch basicType.Kind() {
15
- case types.Int, types.Int8, types.Int16, types.Int32, types.Int64,
16
- types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64,
17
- types.Float32, types.Float64, types.Complex64, types.Complex128:
18
- return "number"
19
- case types.Bool:
20
- return "boolean"
21
- case types.String:
22
- return "string"
23
- }
24
- }
25
- // For other types (structs, interfaces, pointers, etc.), don't provide a hint
26
- // This will use the default null initialization which is appropriate for object types
27
- return ""
28
- }
29
-
30
- // writeMakeChannel writes the TypeScript code for creating a channel with $.makeChannel
31
- // It handles buffer size, zero value, and direction parameters
32
- func (c *GoToTSCompiler) writeMakeChannel(chanType *types.Chan, bufferArg ast.Expr) error {
33
- c.tsw.WriteLiterally("$.makeChannel<")
34
- c.WriteGoType(chanType.Elem(), GoTypeContextGeneral)
35
- c.tsw.WriteLiterally(">(")
36
-
37
- // If buffer size is provided, add it
38
- if bufferArg != nil {
39
- if err := c.WriteValueExpr(bufferArg); err != nil {
40
- return fmt.Errorf("failed to write buffer size in makeChannel: %w", err)
41
- }
42
- } else {
43
- // Default to 0 (unbuffered channel)
44
- c.tsw.WriteLiterally("0")
45
- }
46
-
47
- c.tsw.WriteLiterally(", ") // Add comma for zero value argument
48
-
49
- // Write the zero value for the channel's element type
50
- if chanType.Elem().String() == "struct{}" {
51
- c.tsw.WriteLiterally("{}")
52
- } else {
53
- c.WriteZeroValueForType(chanType.Elem())
54
- }
55
-
56
- // Add direction parameter
57
- c.tsw.WriteLiterally(", ")
58
-
59
- // Determine channel direction
60
- switch chanType.Dir() {
61
- case types.SendRecv:
62
- c.tsw.WriteLiterally("'both'")
63
- case types.SendOnly:
64
- c.tsw.WriteLiterally("'send'")
65
- case types.RecvOnly:
66
- c.tsw.WriteLiterally("'receive'")
67
- default:
68
- c.tsw.WriteLiterally("'both'") // Default to bidirectional
69
- }
70
-
71
- c.tsw.WriteLiterally(")")
72
- return nil
73
- }
74
-
75
- // writeMakeSlice writes the TypeScript code for creating a slice
76
- // It handles []byte special case and generic slice creation
77
- func (c *GoToTSCompiler) writeMakeSlice(sliceType *types.Slice, exp *ast.CallExpr) error {
78
- goElemType := sliceType.Elem()
79
-
80
- // Check if it's []byte
81
- if c.isByteSliceType(sliceType) {
82
- var lengthArg, capacityArg any
83
- if len(exp.Args) >= 2 {
84
- lengthArg = exp.Args[1]
85
- }
86
- if len(exp.Args) == 3 {
87
- capacityArg = exp.Args[2]
88
- }
89
- return c.writeByteSliceCreation(lengthArg, capacityArg)
90
- }
91
-
92
- // Handle other slice types
93
- var lengthArg, capacityArg any
94
- if len(exp.Args) >= 2 {
95
- lengthArg = exp.Args[1]
96
- }
97
- if len(exp.Args) == 3 {
98
- capacityArg = exp.Args[2]
99
- } else if len(exp.Args) > 3 {
100
- return errors.New("makeSlice expects 2 or 3 arguments")
101
- }
102
- return c.writeGenericSliceCreation(goElemType, lengthArg, capacityArg)
103
- }
104
-
105
- // WriteCallExprMake handles make() function calls and translates them to TypeScript.
106
- // It handles channel, map, and slice creation with different type patterns including:
107
- // - Channel creation with different directions
108
- // - Map creation for various type patterns
109
- // - Slice creation with special handling for []byte, generic types, named types, instantiated generics, and selector expressions
110
- func (c *GoToTSCompiler) WriteCallExprMake(exp *ast.CallExpr) error {
111
- // First check if we have a channel type
112
- if typ := c.pkg.TypesInfo.TypeOf(exp.Args[0]); typ != nil {
113
- if chanType, ok := typ.Underlying().(*types.Chan); ok {
114
- // Handle channel creation: make(chan T, bufferSize) or make(chan T)
115
- var bufferArg ast.Expr
116
- if len(exp.Args) >= 2 {
117
- bufferArg = exp.Args[1]
118
- }
119
- return c.writeMakeChannel(chanType, bufferArg)
120
- }
121
- }
122
- // Handle make for slices: make([]T, len, cap) or make([]T, len)
123
- if len(exp.Args) >= 1 {
124
- // Handle map creation: make(map[K]V)
125
- if mapType, ok := exp.Args[0].(*ast.MapType); ok {
126
- c.tsw.WriteLiterally("$.makeMap<")
127
- c.WriteTypeExpr(mapType.Key) // Write the key type
128
- c.tsw.WriteLiterally(", ")
129
- c.WriteTypeExpr(mapType.Value) // Write the value type
130
- c.tsw.WriteLiterally(">()")
131
- return nil // Handled make for map
132
- }
133
-
134
- // Handle slice creation
135
- if _, ok := exp.Args[0].(*ast.ArrayType); ok {
136
- // Get the slice type information
137
- sliceType := c.pkg.TypesInfo.TypeOf(exp.Args[0])
138
- if sliceType == nil {
139
- return errors.New("could not get type information for slice in make call")
140
- }
141
- goUnderlyingType, ok := sliceType.Underlying().(*types.Slice)
142
- if !ok {
143
- return errors.New("expected slice type for make call")
144
- }
145
-
146
- // Check if the element type is a generic type parameter
147
- if _, isTypeParam := goUnderlyingType.Elem().(*types.TypeParam); isTypeParam {
148
- // This is make([]E, n) where E is a type parameter
149
- c.tsw.WriteLiterally("$.makeSlice<")
150
- c.WriteGoType(goUnderlyingType.Elem(), GoTypeContextGeneral) // Write the element type parameter
151
- c.tsw.WriteLiterally(">(")
152
-
153
- if len(exp.Args) >= 2 {
154
- if err := c.WriteValueExpr(exp.Args[1]); err != nil { // Length
155
- return err
156
- }
157
- if len(exp.Args) == 3 {
158
- c.tsw.WriteLiterally(", ")
159
- if err := c.WriteValueExpr(exp.Args[2]); err != nil { // Capacity
160
- return err
161
- }
162
- } else if len(exp.Args) > 3 {
163
- return errors.New("makeSlice expects 2 or 3 arguments")
164
- }
165
- } else {
166
- // If no length is provided, default to 0
167
- c.tsw.WriteLiterally("0")
168
- }
169
- c.tsw.WriteLiterally(")")
170
- return nil // Handled make for []E where E is type parameter
171
- }
172
-
173
- return c.writeMakeSlice(goUnderlyingType, exp)
174
- }
175
-
176
- // Handle generic type parameter make calls: make(S, len, cap) where S ~[]E
177
- if ident, ok := exp.Args[0].(*ast.Ident); ok {
178
- // Check if this identifier refers to a type parameter
179
- if obj := c.pkg.TypesInfo.Uses[ident]; obj != nil {
180
- if typeName, isTypeName := obj.(*types.TypeName); isTypeName {
181
- if typeParam, isTypeParam := typeName.Type().(*types.TypeParam); isTypeParam {
182
- // Check if the type parameter is constrained to slice types
183
- constraint := typeParam.Constraint()
184
- if constraint != nil {
185
- underlying := constraint.Underlying()
186
- if iface, isInterface := underlying.(*types.Interface); isInterface {
187
- // Check if the constraint includes slice types
188
- // For constraints like ~[]E, we need to look at the type terms
189
- if hasSliceConstraint(iface) {
190
- // This is a generic slice type parameter
191
- // We need to determine the element type from the constraint
192
- elemType := getSliceElementTypeFromConstraint(iface)
193
- if elemType != nil {
194
- // Check if it's make(S, ...) where S constrains to []byte
195
- if c.isByteSliceType(types.NewSlice(elemType)) {
196
- var lengthArg, capacityArg any
197
- if len(exp.Args) >= 2 {
198
- lengthArg = exp.Args[1]
199
- }
200
- if len(exp.Args) == 3 {
201
- capacityArg = exp.Args[2]
202
- }
203
- return c.writeByteSliceCreation(lengthArg, capacityArg)
204
- }
205
-
206
- var lengthArg, capacityArg any
207
- if len(exp.Args) >= 2 {
208
- lengthArg = exp.Args[1]
209
- }
210
- if len(exp.Args) == 3 {
211
- capacityArg = exp.Args[2]
212
- } else if len(exp.Args) > 3 {
213
- return errors.New("makeSlice expects 2 or 3 arguments")
214
- }
215
- return c.writeGenericSliceCreation(elemType, lengthArg, capacityArg)
216
- }
217
- }
218
- }
219
- }
220
- } else {
221
- // Handle named types with slice underlying types: make(NamedSliceType, len, cap)
222
- namedType := typeName.Type()
223
- if sliceType, isSlice := namedType.Underlying().(*types.Slice); isSlice {
224
- return c.writeMakeSlice(sliceType, exp)
225
- }
226
-
227
- // Handle named types with map underlying types: make(NamedMapType)
228
- if mapType, isMap := namedType.Underlying().(*types.Map); isMap {
229
- c.tsw.WriteLiterally("$.makeMap<")
230
- c.WriteGoType(mapType.Key(), GoTypeContextGeneral) // Write the key type
231
- c.tsw.WriteLiterally(", ")
232
- c.WriteGoType(mapType.Elem(), GoTypeContextGeneral) // Write the value type
233
- c.tsw.WriteLiterally(">()")
234
- return nil // Handled make for named map type
235
- }
236
-
237
- // Handle named types with channel underlying types: make(NamedChannelType, bufferSize)
238
- if chanType, isChan := namedType.Underlying().(*types.Chan); isChan {
239
- var bufferArg ast.Expr
240
- if len(exp.Args) >= 2 {
241
- bufferArg = exp.Args[1]
242
- }
243
- return c.writeMakeChannel(chanType, bufferArg)
244
- }
245
- }
246
- }
247
- }
248
- }
249
- }
250
- // Handle instantiated generic types: make(GenericType[TypeArg], ...)
251
- // This handles cases like: make(Ints[int64]) where Ints[T] is a generic type
252
- if indexExpr, ok := exp.Args[0].(*ast.IndexExpr); ok {
253
- // Get the type information for the instantiated generic type
254
- if typ := c.pkg.TypesInfo.TypeOf(indexExpr); typ != nil {
255
- // Check the underlying type of the instantiated generic type
256
- underlying := typ.Underlying()
257
-
258
- // Handle instantiated generic map types: make(GenericMap[K, V])
259
- if mapType, isMap := underlying.(*types.Map); isMap {
260
- c.tsw.WriteLiterally("$.makeMap<")
261
- c.WriteGoType(mapType.Key(), GoTypeContextGeneral) // Write the key type
262
- c.tsw.WriteLiterally(", ")
263
- c.WriteGoType(mapType.Elem(), GoTypeContextGeneral) // Write the value type
264
- c.tsw.WriteLiterally(">()")
265
- return nil // Handled make for instantiated generic map type
266
- }
267
-
268
- // Handle instantiated generic slice types: make(GenericSlice[T], len, cap)
269
- if sliceType, isSlice := underlying.(*types.Slice); isSlice {
270
- return c.writeMakeSlice(sliceType, exp)
271
- }
272
-
273
- // Handle instantiated generic channel types: make(GenericChannel[T], bufferSize)
274
- if chanType, isChan := underlying.(*types.Chan); isChan {
275
- var bufferArg ast.Expr
276
- if len(exp.Args) >= 2 {
277
- bufferArg = exp.Args[1]
278
- }
279
- return c.writeMakeChannel(chanType, bufferArg)
280
- }
281
- }
282
- }
283
- // Handle selector expressions: make(pkg.TypeName, ...)
284
- // This handles cases like: make(fstest.MapFS) where fstest.MapFS is map[string]*MapFile
285
- if selectorExpr, ok := exp.Args[0].(*ast.SelectorExpr); ok {
286
- // Get the type information for the selector expression
287
- if typ := c.pkg.TypesInfo.TypeOf(selectorExpr); typ != nil {
288
- // Check the underlying type of the selector expression
289
- underlying := typ.Underlying()
290
-
291
- // Handle selector expression map types: make(pkg.MapType)
292
- if mapType, isMap := underlying.(*types.Map); isMap {
293
- c.tsw.WriteLiterally("$.makeMap<")
294
- c.WriteGoType(mapType.Key(), GoTypeContextGeneral) // Write the key type
295
- c.tsw.WriteLiterally(", ")
296
- c.WriteGoType(mapType.Elem(), GoTypeContextGeneral) // Write the value type
297
- c.tsw.WriteLiterally(">()")
298
- return nil // Handled make for selector expression map type
299
- }
300
-
301
- // Handle selector expression slice types: make(pkg.SliceType, len, cap)
302
- if sliceType, isSlice := underlying.(*types.Slice); isSlice {
303
- return c.writeMakeSlice(sliceType, exp)
304
- }
305
-
306
- // Handle selector expression channel types: make(pkg.ChannelType, bufferSize)
307
- if chanType, isChan := underlying.(*types.Chan); isChan {
308
- var bufferArg ast.Expr
309
- if len(exp.Args) >= 2 {
310
- bufferArg = exp.Args[1]
311
- }
312
- return c.writeMakeChannel(chanType, bufferArg)
313
- }
314
- }
315
- }
316
- // Fallthrough for unhandled make calls (e.g., channels)
317
- return errors.New("unhandled make call")
318
- }