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,442 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "go/ast"
5
- "go/types"
6
- )
7
-
8
- // WriteTypeExpr translates a Go abstract syntax tree (AST) expression (`ast.Expr`)
9
- // that represents a type into its TypeScript type equivalent using type information.
10
- //
11
- // It handles various Go type expressions:
12
- // - Basic types (e.g., int, string, bool) -> TypeScript primitives (number, string, boolean)
13
- // - Named types -> TypeScript class/interface names
14
- // - Pointer types (`*T`) -> `$.VarRef<T_ts> | null`
15
- // - Slice types (`[]T`) -> `$.Slice<T_ts>`
16
- // - Array types (`[N]T`) -> `T_ts[]`
17
- // - Map types (`map[K]V`) -> `Map<K_ts, V_ts>`
18
- // - Channel types (`chan T`) -> `$.Channel<T_ts>`
19
- // - Struct types -> TypeScript object types or class names
20
- // - Interface types -> TypeScript interface types or "any"
21
- // - Function types -> TypeScript function signatures
22
- func (c *GoToTSCompiler) WriteTypeExpr(a ast.Expr) {
23
- // Handle qualified generic type references (e.g., pkg.Type[T]) preserving the package alias.
24
- if indexExpr, ok := a.(*ast.IndexExpr); ok {
25
- if selectorExpr, ok := indexExpr.X.(*ast.SelectorExpr); ok {
26
- if pkgIdent, ok := selectorExpr.X.(*ast.Ident); ok {
27
- if obj := c.pkg.TypesInfo.Uses[pkgIdent]; obj != nil {
28
- if _, isPkg := obj.(*types.PkgName); isPkg {
29
- c.tsw.WriteLiterally(pkgIdent.Name)
30
- c.tsw.WriteLiterally(".")
31
- c.tsw.WriteLiterally(selectorExpr.Sel.Name)
32
- c.tsw.WriteLiterally("<")
33
- c.WriteTypeExpr(indexExpr.Index)
34
- c.tsw.WriteLiterally(">")
35
- return
36
- }
37
- }
38
- }
39
- }
40
- }
41
-
42
- if indexListExpr, ok := a.(*ast.IndexListExpr); ok {
43
- if selectorExpr, ok := indexListExpr.X.(*ast.SelectorExpr); ok {
44
- if pkgIdent, ok := selectorExpr.X.(*ast.Ident); ok {
45
- if obj := c.pkg.TypesInfo.Uses[pkgIdent]; obj != nil {
46
- if _, isPkg := obj.(*types.PkgName); isPkg {
47
- c.tsw.WriteLiterally(pkgIdent.Name)
48
- c.tsw.WriteLiterally(".")
49
- c.tsw.WriteLiterally(selectorExpr.Sel.Name)
50
- c.tsw.WriteLiterally("<")
51
- for i, index := range indexListExpr.Indices {
52
- if i > 0 {
53
- c.tsw.WriteLiterally(", ")
54
- }
55
- c.WriteTypeExpr(index)
56
- }
57
- c.tsw.WriteLiterally(">")
58
- return
59
- }
60
- }
61
- }
62
- }
63
- }
64
-
65
- // Handle selector expressions (e.g., os.FileInfo) specially to preserve qualified names
66
- if selectorExpr, ok := a.(*ast.SelectorExpr); ok {
67
- if pkgIdent, ok := selectorExpr.X.(*ast.Ident); ok {
68
- // Check if this is a package selector (e.g., os.FileInfo)
69
- if obj := c.pkg.TypesInfo.Uses[pkgIdent]; obj != nil {
70
- if _, isPkg := obj.(*types.PkgName); isPkg {
71
- // This is a package.Type reference
72
- typ := c.pkg.TypesInfo.TypeOf(a)
73
-
74
- // Check if this is an interface type and add null | prefix
75
- if typ != nil {
76
- if _, isInterface := typ.Underlying().(*types.Interface); isInterface {
77
- c.tsw.WriteLiterally("null | ")
78
- }
79
- }
80
-
81
- // Write the qualified name
82
- c.tsw.WriteLiterally(pkgIdent.Name)
83
- c.tsw.WriteLiterally(".")
84
- c.tsw.WriteLiterally(selectorExpr.Sel.Name)
85
-
86
- // Check if this is a function type and add | null
87
- if typ != nil {
88
- if namedType, isNamed := typ.(*types.Named); isNamed {
89
- if _, isSignature := namedType.Underlying().(*types.Signature); isSignature {
90
- c.tsw.WriteLiterally(" | null")
91
- }
92
- }
93
- }
94
- return
95
- }
96
- }
97
- }
98
- }
99
-
100
- // Handle array/slice types to preserve qualified names in element types
101
- if arrayType, ok := a.(*ast.ArrayType); ok {
102
- if arrayType.Len == nil {
103
- // Slice type: []T -> $.Slice<T>
104
- // Check if it's a []byte slice first
105
- if ident, ok := arrayType.Elt.(*ast.Ident); ok && ident.Name == "byte" {
106
- c.tsw.WriteLiterally("$.Bytes")
107
- return
108
- }
109
- c.tsw.WriteLiterally("$.Slice<")
110
- c.WriteTypeExpr(arrayType.Elt) // Recursively handle element type preserving qualified names
111
- c.tsw.WriteLiterally(">")
112
- } else {
113
- // Array type: [N]T -> T[]
114
- c.WriteTypeExpr(arrayType.Elt) // Recursively handle element type preserving qualified names
115
- c.tsw.WriteLiterally("[]")
116
- }
117
- return
118
- }
119
-
120
- // Get type information for the expression and use WriteGoType
121
- typ := c.pkg.TypesInfo.TypeOf(a)
122
- c.WriteGoType(typ, GoTypeContextGeneral)
123
- }
124
-
125
- // writeTypeDescription writes the TypeInfo for a type expr.
126
- func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
127
- switch t := typeExpr.(type) {
128
- case *ast.Ident:
129
- // Resolve the identifier to its type
130
- goType := c.pkg.TypesInfo.TypeOf(t)
131
- if goType != nil {
132
- if namedType, isNamed := goType.(*types.Named); isNamed {
133
- if sig, isFuncSig := namedType.Underlying().(*types.Signature); isFuncSig {
134
- // It's a named function type (e.g. type MyFunc func())
135
- c.tsw.WriteLiterally("{")
136
- c.tsw.WriteLiterally("kind: $.TypeKind.Function, ")
137
- c.tsw.WriteLiterallyf("name: '%s'", namedType.Obj().Name()) // Use the original defined name
138
-
139
- // Add params if present
140
- if sig.Params() != nil && sig.Params().Len() > 0 {
141
- c.tsw.WriteLiterally(", params: [")
142
- for i := 0; i < sig.Params().Len(); i++ {
143
- if i > 0 {
144
- c.tsw.WriteLiterally(", ")
145
- }
146
- paramVar := sig.Params().At(i)
147
- c.writeTypeInfoObject(paramVar.Type())
148
- }
149
- c.tsw.WriteLiterally("]")
150
- } else {
151
- c.tsw.WriteLiterally(", params: []")
152
- }
153
-
154
- // Add results if present
155
- if sig.Results() != nil && sig.Results().Len() > 0 {
156
- c.tsw.WriteLiterally(", results: [")
157
- for i := 0; i < sig.Results().Len(); i++ {
158
- if i > 0 {
159
- c.tsw.WriteLiterally(", ")
160
- }
161
- resultVar := sig.Results().At(i)
162
- c.writeTypeInfoObject(resultVar.Type())
163
- }
164
- c.tsw.WriteLiterally("]")
165
- } else {
166
- c.tsw.WriteLiterally(", results: []")
167
- }
168
-
169
- c.tsw.WriteLiterally("}")
170
- return
171
- }
172
- }
173
- }
174
-
175
- if isPrimitiveType(t.Name) {
176
- if tsType, ok := GoBuiltinToTypescript(t.Name); ok {
177
- c.tsw.WriteLiterally("{")
178
- c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
179
- c.tsw.WriteLiterallyf("name: '%s'", tsType)
180
- c.tsw.WriteLiterally("}")
181
- } else {
182
- // Fallback for other primitive types
183
- c.tsw.WriteLiterally("{")
184
- c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
185
- c.tsw.WriteLiterallyf("name: '%s'", t.Name)
186
- c.tsw.WriteLiterally("}")
187
- }
188
- } else {
189
- // For named types, use the fully qualified name with package path
190
- if goType != nil {
191
- if namedType, isNamed := goType.(*types.Named); isNamed {
192
- typeName := namedType.Obj().Name()
193
- if pkg := namedType.Obj().Pkg(); pkg != nil {
194
- pkgPath := pkg.Path()
195
- pkgName := pkg.Name()
196
- if pkgPath != "" && pkgName != "main" {
197
- typeName = pkgPath + "." + typeName
198
- } else if pkgName == "main" {
199
- typeName = "main." + typeName
200
- }
201
- }
202
- c.tsw.WriteLiterallyf("'%s'", typeName)
203
- return
204
- }
205
- }
206
- // Fallback to short name if type info unavailable
207
- c.tsw.WriteLiterallyf("'%s'", t.Name)
208
- }
209
- case *ast.SelectorExpr:
210
- if ident, ok := t.X.(*ast.Ident); ok {
211
- // Use type info to get the actual package path
212
- goType := c.pkg.TypesInfo.TypeOf(t)
213
- if goType != nil {
214
- if namedType, isNamed := goType.(*types.Named); isNamed {
215
- typeName := namedType.Obj().Name()
216
- if pkg := namedType.Obj().Pkg(); pkg != nil {
217
- pkgPath := pkg.Path()
218
- pkgName := pkg.Name()
219
- if pkgPath != "" && pkgName != "main" {
220
- typeName = pkgPath + "." + typeName
221
- } else if pkgName == "main" {
222
- typeName = "main." + typeName
223
- }
224
- }
225
- c.tsw.WriteLiterallyf("'%s'", typeName)
226
- return
227
- }
228
- }
229
- // Fallback to using the identifier name (package alias)
230
- c.tsw.WriteLiterallyf("'%s.%s'", ident.Name, t.Sel.Name)
231
- }
232
- case *ast.ArrayType:
233
- typeKind := "$.TypeKind.Slice"
234
- if t.Len != nil {
235
- typeKind = "$.TypeKind.Array"
236
- }
237
-
238
- c.tsw.WriteLiterally("{")
239
- c.tsw.WriteLiterallyf("kind: %s, ", typeKind)
240
- c.tsw.WriteLiterally("elemType: ")
241
- c.writeTypeDescription(t.Elt)
242
- c.tsw.WriteLiterally("}")
243
- case *ast.StructType:
244
- c.tsw.WriteLiterally("{")
245
- c.tsw.WriteLiterally("kind: $.TypeKind.Struct, ")
246
-
247
- // Add field names and types to the struct type info
248
- if t.Fields != nil && t.Fields.List != nil {
249
- c.tsw.WriteLiterally("fields: {")
250
-
251
- hasFields := false
252
- for _, field := range t.Fields.List {
253
- if len(field.Names) > 0 {
254
- for _, name := range field.Names {
255
- if hasFields {
256
- c.tsw.WriteLiterally(", ")
257
- }
258
- c.tsw.WriteLiterallyf("'%s': ", name.Name)
259
- c.writeTypeDescription(field.Type)
260
- hasFields = true
261
- }
262
- }
263
- }
264
-
265
- c.tsw.WriteLiterally("}, ")
266
- } else {
267
- c.tsw.WriteLiterally("fields: {}, ")
268
- }
269
-
270
- c.tsw.WriteLiterally("methods: []")
271
-
272
- c.tsw.WriteLiterally("}")
273
- case *ast.MapType:
274
- c.tsw.WriteLiterally("{")
275
- c.tsw.WriteLiterally("kind: $.TypeKind.Map, ")
276
- c.tsw.WriteLiterally("keyType: ")
277
- c.writeTypeDescription(t.Key)
278
- c.tsw.WriteLiterally(", ")
279
- c.tsw.WriteLiterally("elemType: ")
280
- c.writeTypeDescription(t.Value)
281
- c.tsw.WriteLiterally("}")
282
- case *ast.StarExpr:
283
- c.tsw.WriteLiterally("{")
284
- c.tsw.WriteLiterally("kind: $.TypeKind.Pointer, ")
285
- c.tsw.WriteLiterally("elemType: ")
286
- c.writeTypeDescription(t.X)
287
- c.tsw.WriteLiterally("}")
288
- case *ast.FuncType:
289
- // For function types, create a type descriptor object with params and results
290
- c.tsw.WriteLiterally("{")
291
- c.tsw.WriteLiterally("kind: $.TypeKind.Function")
292
-
293
- // Add name if this is a named function type
294
- // For an anonymous ast.FuncType, typeExpr is the ast.FuncType itself.
295
- // We need to check if the type information associated with this AST node
296
- // points to a *types.Named type.
297
- resolvedGoType := c.pkg.TypesInfo.TypeOf(typeExpr)
298
- if resolvedGoType != nil {
299
- if named, ok := resolvedGoType.(*types.Named); ok {
300
- // Ensure it's actually a function type that's named
301
- if _, isFuncSig := named.Underlying().(*types.Signature); isFuncSig {
302
- c.tsw.WriteLiterallyf(", name: '%s'", named.Obj().Name())
303
- }
304
- }
305
- }
306
-
307
- // Add params if present
308
- if t.Params != nil && len(t.Params.List) > 0 {
309
- c.tsw.WriteLiterally(", params: [")
310
- for i, param := range t.Params.List {
311
- if i > 0 {
312
- c.tsw.WriteLiterally(", ")
313
- }
314
- c.writeTypeDescription(param.Type)
315
- }
316
- c.tsw.WriteLiterally("]")
317
- }
318
-
319
- // Add results if present
320
- if t.Results != nil && len(t.Results.List) > 0 {
321
- c.tsw.WriteLiterally(", results: [")
322
- for i, result := range t.Results.List {
323
- if i > 0 {
324
- c.tsw.WriteLiterally(", ")
325
- }
326
- c.writeTypeDescription(result.Type)
327
- }
328
- c.tsw.WriteLiterally("]")
329
- }
330
-
331
- c.tsw.WriteLiterally("}")
332
- return
333
- case *ast.ChanType:
334
- c.tsw.WriteLiterally("{")
335
- c.tsw.WriteLiterally("kind: $.TypeKind.Channel, ")
336
- c.tsw.WriteLiterally("elemType: ")
337
-
338
- // Add element type
339
- if ident, ok := t.Value.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
340
- if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
341
- c.tsw.WriteLiterallyf("'%s'", tsType)
342
- } else {
343
- c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
344
- }
345
- } else {
346
- c.writeTypeDescription(t.Value)
347
- }
348
-
349
- // Add direction
350
- c.tsw.WriteLiterally(", direction: ")
351
- switch t.Dir {
352
- case ast.SEND:
353
- c.tsw.WriteLiterally("'send'")
354
- case ast.RECV:
355
- c.tsw.WriteLiterally("'receive'")
356
- case ast.SEND | ast.RECV: // bidirectional
357
- c.tsw.WriteLiterally("'both'")
358
- default:
359
- // This should not happen, but just in case
360
- c.tsw.WriteLiterally("'both'")
361
- }
362
-
363
- c.tsw.WriteLiterally("}")
364
- case *ast.InterfaceType:
365
- // Handle inline interface types like interface{ Method() string }
366
- c.tsw.WriteLiterally("{")
367
- c.tsw.WriteLiterally("kind: $.TypeKind.Interface, ")
368
- c.tsw.WriteLiterally("methods: [")
369
-
370
- // Add method signatures for each method in the interface
371
- if t.Methods != nil && t.Methods.List != nil {
372
- hasMethod := false
373
- for _, field := range t.Methods.List {
374
- // Only process method declarations (not embedded interfaces)
375
- if len(field.Names) > 0 {
376
- for _, methodName := range field.Names {
377
- if hasMethod {
378
- c.tsw.WriteLiterally(", ")
379
- }
380
- hasMethod = true
381
-
382
- // Write method signature in the same format as writeMethodSignatures
383
- c.tsw.WriteLiterallyf("{ name: '%s', args: [", methodName.Name)
384
-
385
- // Get the function type for this method
386
- if funcType, ok := field.Type.(*ast.FuncType); ok {
387
- // Add parameters
388
- if funcType.Params != nil && funcType.Params.List != nil {
389
- paramIndex := 0
390
- for _, param := range funcType.Params.List {
391
- // Each parameter field can declare multiple variables of the same type
392
- if len(param.Names) > 0 {
393
- for _, paramName := range param.Names {
394
- if paramIndex > 0 {
395
- c.tsw.WriteLiterally(", ")
396
- }
397
- c.tsw.WriteLiterallyf("{ name: '%s', type: ", paramName.Name)
398
- c.writeTypeDescription(param.Type)
399
- c.tsw.WriteLiterally(" }")
400
- paramIndex++
401
- }
402
- } else {
403
- // No names, create a generic parameter name
404
- if paramIndex > 0 {
405
- c.tsw.WriteLiterally(", ")
406
- }
407
- c.tsw.WriteLiterallyf("{ name: '_p%d', type: ", paramIndex)
408
- c.writeTypeDescription(param.Type)
409
- c.tsw.WriteLiterally(" }")
410
- paramIndex++
411
- }
412
- }
413
- }
414
-
415
- c.tsw.WriteLiterally("], returns: [")
416
-
417
- // Add return types
418
- if funcType.Results != nil && funcType.Results.List != nil {
419
- for i, result := range funcType.Results.List {
420
- if i > 0 {
421
- c.tsw.WriteLiterally(", ")
422
- }
423
- c.tsw.WriteLiterally("{ type: ")
424
- c.writeTypeDescription(result.Type)
425
- c.tsw.WriteLiterally(" }")
426
- }
427
- }
428
-
429
- c.tsw.WriteLiterally("] }")
430
- }
431
- }
432
- }
433
- }
434
- }
435
-
436
- c.tsw.WriteLiterally("]")
437
- c.tsw.WriteLiterally("}")
438
- default:
439
- // For other types, use the string representation
440
- c.tsw.WriteLiterallyf("'%s'", c.getTypeNameString(typeExpr))
441
- }
442
- }
@@ -1,89 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "go/ast"
5
- )
6
-
7
- // WriteValueExpr translates a Go abstract syntax tree (AST) expression (`ast.Expr`)
8
- // that represents a value into its TypeScript value equivalent.
9
- // This is a central dispatch function for various expression types:
10
- // - Identifiers (`ast.Ident`): Delegates to `WriteIdent`, potentially adding `.value` for varrefed variables.
11
- // - Selector expressions (`ast.SelectorExpr`, e.g., `obj.Field` or `pkg.Var`): Delegates to `WriteSelectorExpr`.
12
- // - Pointer dereferences (`ast.StarExpr`, e.g., `*ptr`): Delegates to `WriteStarExpr`.
13
- // - Function calls (`ast.CallExpr`): Delegates to `WriteCallExpr`.
14
- // - Unary operations (`ast.UnaryExpr`, e.g., `!cond`, `&val`): Delegates to `WriteUnaryExpr`.
15
- // - Binary operations (`ast.BinaryExpr`, e.g., `a + b`): Delegates to `WriteBinaryExpr`.
16
- // - Basic literals (`ast.BasicLit`, e.g., `123`, `"hello"`): Delegates to `WriteBasicLit`.
17
- // - Composite literals (`ast.CompositeLit`, e.g., `MyStruct{}`): Delegates to `WriteCompositeLit`.
18
- // - Key-value expressions (`ast.KeyValueExpr`): Delegates to `WriteKeyValueExpr`.
19
- // - Type assertions in expression context (`ast.TypeAssertExpr`, e.g., `val.(Type)`): Delegates to `WriteTypeAssertExpr`.
20
- // - Index expressions (`ast.IndexExpr`):
21
- // - For maps: `myMap[key]` becomes `myMap.get(key) ?? zeroValue`.
22
- // - For arrays/slices: `myArray[idx]` becomes `myArray![idx]`.
23
- //
24
- // - Slice expressions (`ast.SliceExpr`, e.g., `s[low:high:max]`): Translates to `$.slice(s, low, high, max)`.
25
- // - Parenthesized expressions (`ast.ParenExpr`): Translates `(X)` to `(X)`.
26
- // - Function literals (`ast.FuncLit`): Delegates to `WriteFuncLitValue`.
27
- // Unhandled value expressions result in a comment.
28
- func (c *GoToTSCompiler) WriteValueExpr(a ast.Expr) error {
29
- switch exp := a.(type) {
30
- case *ast.Ident:
31
- c.WriteIdent(exp, true) // adds .value accessor
32
- return nil
33
- case *ast.SelectorExpr:
34
- return c.WriteSelectorExpr(exp)
35
- case *ast.StarExpr:
36
- return c.WriteStarExpr(exp)
37
- case *ast.CallExpr:
38
- return c.WriteCallExpr(exp)
39
- case *ast.UnaryExpr:
40
- return c.WriteUnaryExpr(exp)
41
- case *ast.BinaryExpr:
42
- return c.WriteBinaryExpr(exp)
43
- case *ast.BasicLit:
44
- c.WriteBasicLit(exp)
45
- return nil
46
- case *ast.CompositeLit:
47
- return c.WriteCompositeLit(exp)
48
- case *ast.KeyValueExpr:
49
- return c.WriteKeyValueExpr(exp)
50
- case *ast.TypeAssertExpr:
51
- // Handle type assertion in an expression context
52
- return c.WriteTypeAssertExpr(exp)
53
- case *ast.IndexExpr:
54
- return c.WriteIndexExpr(exp)
55
- case *ast.IndexListExpr:
56
- // Handle generic function instantiation: f[T1, T2](args) -> f<T1, T2>(args)
57
- return c.WriteIndexListExpr(exp)
58
- case *ast.SliceExpr:
59
- return c.WriteSliceExpr(exp)
60
- case *ast.ParenExpr:
61
- // Check if this is a nil pointer to struct type cast: (*struct{})(nil)
62
- if starExpr, isStarExpr := exp.X.(*ast.StarExpr); isStarExpr {
63
- if _, isStructType := starExpr.X.(*ast.StructType); isStructType {
64
- c.tsw.WriteLiterally("null")
65
- return nil
66
- }
67
- }
68
-
69
- // Check if this is a type cast with nil: (SomeType)(nil)
70
- if ident, isIdent := exp.X.(*ast.Ident); isIdent && ident.Name == "nil" {
71
- c.tsw.WriteLiterally("null")
72
- return nil
73
- }
74
-
75
- // Translate (X) to (X)
76
- // If we haven't written anything in this statement yet, prepend ;
77
- c.tsw.WriteLiterally("(")
78
- if err := c.WriteValueExpr(exp.X); err != nil {
79
- return err
80
- }
81
- c.tsw.WriteLiterally(")")
82
- return nil
83
- case *ast.FuncLit:
84
- return c.WriteFuncLitValue(exp)
85
- default:
86
- c.tsw.WriteCommentLinef("unhandled value expr: %T", exp)
87
- return nil
88
- }
89
- }