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,413 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "fmt"
5
- "go/ast"
6
- "go/token"
7
- "go/types"
8
- )
9
-
10
- // WriteCallExpr translates a Go function call expression (`ast.CallExpr`)
11
- // into its TypeScript equivalent.
12
- // It handles several Go built-in functions specially:
13
- // - `println(...)` becomes `console.log(...)`.
14
- // - `panic(...)` becomes `$.panic(...)`.
15
- // - `len(arg)` becomes `$.len(arg)`.
16
- // - `cap(arg)` becomes `$.cap(arg)`.
17
- // - `delete(m, k)` becomes `$.deleteMapEntry(m, k)`.
18
- // - `make(chan T, size)` becomes `$.makeChannel<T_ts>(size, zeroValueForT)`.
19
- // - `make(map[K]V)` becomes `$.makeMap<K_ts, V_ts>()`.
20
- // - `make([]T, len, cap)` becomes `$.makeSlice<T_ts>(len, cap)`.
21
- // - `make([]byte, len, cap)` becomes `new Uint8Array(len)`.
22
- // - `string(runeVal)` becomes `$.runeOrStringToString(runeVal)`.
23
- // - `string([]runeVal)` becomes `$.runesToString(sliceVal)`.
24
- // - `string([]byteVal)` becomes `$.bytesToString(sliceVal)`.
25
- // - `[]rune(stringVal)` becomes `$.stringToRunes(stringVal)".
26
- // - `[]byte(stringVal)` becomes `$.stringToBytes(stringVal)`.
27
- // - `close(ch)` becomes `ch.close()`.
28
- // - `append(slice, elems...)` becomes `$.append(slice, elems...)`.
29
- // - `byte(val)` becomes `$.byte(val)`.
30
- // For other function calls:
31
- // - If the `Analysis` data indicates the function is asynchronous (e.g., due to
32
- // channel operations or `go`/`defer` usage within it), the call is prefixed with `await`.
33
- // - Otherwise, it's translated as a standard TypeScript function call: `funcName(arg1, arg2)`.
34
- //
35
- // Arguments are recursively translated using `WriteValueExpr`.
36
- func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
37
- expFun := exp.Fun
38
-
39
- // Handle protobuf method calls
40
- if handled, err := c.writeProtobufMethodCall(exp); handled {
41
- return err
42
- }
43
-
44
- // Handle any type conversion with nil argument
45
- if handled, err := c.writeNilConversion(exp); handled {
46
- return err
47
- }
48
-
49
- // Handle array type conversions like []rune(string)
50
- if handled, err := c.writeArrayTypeConversion(exp); handled {
51
- return err
52
- }
53
-
54
- // Handle built-in functions called as identifiers
55
- if funIdent, funIsIdent := expFun.(*ast.Ident); funIsIdent {
56
- // Check for built-in functions first
57
- if handled, err := c.writeBuiltinFunction(exp, funIdent.String()); handled {
58
- if err != nil {
59
- return err
60
- }
61
- // For built-ins that don't return early, write the arguments
62
- if funIdent.String() != "new" && funIdent.String() != "close" && funIdent.String() != "make" &&
63
- funIdent.String() != "string" && funIdent.String() != "append" && funIdent.String() != "byte" &&
64
- funIdent.String() != "int" && funIdent.String() != "min" && funIdent.String() != "max" &&
65
- funIdent.String() != "clear" {
66
- return c.writeCallArguments(exp)
67
- }
68
- return nil
69
- }
70
-
71
- // Check for type conversions
72
- if handled, err := c.writeTypeConversion(exp, funIdent); handled {
73
- return err
74
- }
75
-
76
- // Check if this is an async function call
77
- c.writeAsyncCallIfNeeded(exp)
78
-
79
- // Not a special built-in, treat as a regular function call
80
- if err := c.WriteValueExpr(expFun); err != nil {
81
- return fmt.Errorf("failed to write function expression in call: %w", err)
82
- }
83
-
84
- c.addNonNullAssertion(expFun)
85
- return c.writeCallArguments(exp)
86
- }
87
-
88
- // Handle qualified type conversions like os.FileMode(value)
89
- if selectorExpr, ok := expFun.(*ast.SelectorExpr); ok {
90
- if handled, err := c.writeQualifiedTypeConversion(exp, selectorExpr); handled {
91
- return err
92
- }
93
-
94
- // Handle wrapper type method calls: obj.Method() -> TypeName_Method(obj, ...)
95
- if handled, err := c.writeWrapperTypeMethodCall(exp, selectorExpr); handled {
96
- return err
97
- }
98
- }
99
-
100
- // Handle reflect.TypeFor[T]() - Fun is IndexExpr where X is SelectorExpr
101
- if indexExpr, ok := expFun.(*ast.IndexExpr); ok {
102
- if selectorExpr, ok := indexExpr.X.(*ast.SelectorExpr); ok {
103
- if handled, err := c.writeReflectTypeAssert(exp, selectorExpr); handled {
104
- return err
105
- }
106
- if handled, err := c.writeReflectTypeFor(exp, selectorExpr); handled {
107
- return err
108
- }
109
- }
110
- }
111
-
112
- // Handle non-identifier function expressions (method calls, function literals, etc.)
113
- // Check if this is an async method call (e.g., mu.Lock())
114
- c.writeAsyncCallIfNeeded(exp)
115
-
116
- // If expFun is a function literal, it needs to be wrapped in parentheses for IIFE syntax
117
- if _, isFuncLit := expFun.(*ast.FuncLit); isFuncLit {
118
- c.tsw.WriteLiterally("(")
119
- if err := c.WriteValueExpr(expFun); err != nil {
120
- return fmt.Errorf("failed to write function literal in call: %w", err)
121
- }
122
- c.tsw.WriteLiterally(")")
123
- } else {
124
- // Check if this is a function call that returns a function (e.g., simpleIterator(m)())
125
- // and if the inner call is async, wrap it in parentheses
126
- innerCallExpr, isCallExpr := expFun.(*ast.CallExpr)
127
- needsParens := isCallExpr && c.isCallExprAsync(innerCallExpr)
128
-
129
- if needsParens {
130
- c.tsw.WriteLiterally("(")
131
- }
132
-
133
- // Not an identifier (e.g., method call on a value, function call result)
134
- if err := c.WriteValueExpr(expFun); err != nil {
135
- return fmt.Errorf("failed to write method expression in call: %w", err)
136
- }
137
-
138
- if needsParens {
139
- c.tsw.WriteLiterally(")")
140
- }
141
-
142
- // Add non-null assertion since the returned function could be null
143
- if isCallExpr {
144
- c.tsw.WriteLiterally("!")
145
- } else {
146
- c.addNonNullAssertion(expFun)
147
- }
148
- }
149
-
150
- return c.writeCallArguments(exp)
151
- }
152
-
153
- // writeCallArguments writes the argument list for a function call
154
- func (c *GoToTSCompiler) writeCallArguments(exp *ast.CallExpr) error {
155
- c.tsw.WriteLiterally("(")
156
-
157
- // Get function signature for parameter type checking
158
- var funcSig *types.Signature
159
- if c.pkg != nil && c.pkg.TypesInfo != nil {
160
- if funcType := c.pkg.TypesInfo.TypeOf(exp.Fun); funcType != nil {
161
- if sig, ok := funcType.(*types.Signature); ok {
162
- funcSig = sig
163
- }
164
- }
165
- }
166
-
167
- for i, arg := range exp.Args {
168
- if i != 0 {
169
- c.tsw.WriteLiterally(", ")
170
- }
171
- // Check if this is the last argument and we have ellipsis (variadic call)
172
- if exp.Ellipsis != token.NoPos && i == len(exp.Args)-1 {
173
- c.tsw.WriteLiterally("...(")
174
- // Write the argument
175
- if err := c.writeArgumentWithTypeHandling(arg, funcSig, i); err != nil {
176
- return err
177
- }
178
- // Add null coalescing for slice spread to prevent TypeScript errors
179
- c.tsw.WriteLiterally(" ?? [])")
180
- continue
181
- }
182
-
183
- if err := c.writeArgumentWithTypeHandling(arg, funcSig, i); err != nil {
184
- return err
185
- }
186
- }
187
-
188
- c.tsw.WriteLiterally(")")
189
- return nil
190
- }
191
-
192
- // writeArgumentWithTypeHandling writes a single argument with proper type handling
193
- func (c *GoToTSCompiler) writeArgumentWithTypeHandling(arg ast.Expr, funcSig *types.Signature, argIndex int) error {
194
- if funcSig != nil && argIndex < funcSig.Params().Len() {
195
- paramType := funcSig.Params().At(argIndex).Type()
196
- isWrapper := c.isWrapperType(paramType)
197
-
198
- if isWrapper {
199
- // For wrapper types (now type aliases), no auto-wrapping is needed
200
- // Just use type casting if the types don't match exactly
201
- argType := c.pkg.TypesInfo.TypeOf(arg)
202
-
203
- // Only add type casting if needed
204
- if argType != nil && !types.Identical(argType, paramType) {
205
- c.tsw.WriteLiterally("(")
206
- if err := c.WriteValueExpr(arg); err != nil {
207
- return fmt.Errorf("failed to write argument for type cast: %w", err)
208
- }
209
- c.tsw.WriteLiterally(" as ")
210
- c.WriteGoType(paramType, GoTypeContextGeneral)
211
- c.tsw.WriteLiterally(")")
212
- } else {
213
- // Types match, just write the argument directly
214
- if err := c.WriteValueExpr(arg); err != nil {
215
- return fmt.Errorf("failed to write argument: %w", err)
216
- }
217
- }
218
- return nil
219
- }
220
- }
221
-
222
- // For non-wrapper types, normal argument writing
223
- if err := c.WriteValueExpr(arg); err != nil {
224
- return fmt.Errorf("failed to write argument: %w", err)
225
- }
226
- return nil
227
- }
228
-
229
- // resolveImportAlias returns the import alias for a given package.
230
- // This is the single source of truth for import alias resolution.
231
- func (c *GoToTSCompiler) resolveImportAlias(pkg *types.Package) (alias string, found bool) {
232
- if c.analysis == nil || pkg == nil {
233
- return "", false
234
- }
235
-
236
- pkgName := pkg.Name()
237
-
238
- // Try to match by the actual package name in regular imports
239
- if _, exists := c.analysis.Imports[pkgName]; exists {
240
- return pkgName, true
241
- }
242
-
243
- // Also check synthetic imports for the current file
244
- if syntheticImports := c.analysis.SyntheticImportsPerFile[c.currentFilePath]; syntheticImports != nil {
245
- if _, exists := syntheticImports[pkgName]; exists {
246
- return pkgName, true
247
- }
248
- }
249
-
250
- return "", false
251
- }
252
-
253
- // getQualifiedTypeName returns the qualified type name for a Named or Alias type
254
- // Returns empty string if the type is not Named or Alias, or has no valid object
255
- func (c *GoToTSCompiler) getQualifiedTypeName(t types.Type) string {
256
- var obj *types.TypeName
257
-
258
- if namedType, ok := t.(*types.Named); ok {
259
- obj = namedType.Obj()
260
- } else if aliasType, ok := t.(*types.Alias); ok {
261
- obj = aliasType.Obj()
262
- }
263
-
264
- if obj == nil || obj.Pkg() == nil {
265
- return ""
266
- }
267
-
268
- if obj.Pkg() != c.pkg.Types {
269
- // Imported type
270
- if alias, found := c.resolveImportAlias(obj.Pkg()); found {
271
- return alias + "." + obj.Name()
272
- }
273
- return obj.Name()
274
- }
275
-
276
- // Local type
277
- return obj.Name()
278
- }
279
-
280
- // writeAutoWrappedArgument writes an argument, auto-wrapping it if needed based on the expected parameter type
281
- func (c *GoToTSCompiler) writeAutoWrappedArgument(arg ast.Expr, expectedType types.Type) error {
282
- // For wrapper types (now type aliases), no auto-wrapping is needed
283
- // Just use type casting if the types don't match exactly
284
- if c.isWrapperType(expectedType) {
285
- argType := c.pkg.TypesInfo.TypeOf(arg)
286
-
287
- // Only add type casting if needed
288
- if argType != nil && !types.Identical(argType, expectedType) {
289
- c.tsw.WriteLiterally("(")
290
- if err := c.WriteValueExpr(arg); err != nil {
291
- return fmt.Errorf("failed to write argument for wrapper type cast: %w", err)
292
- }
293
- c.tsw.WriteLiterally(" as ")
294
- c.WriteGoType(expectedType, GoTypeContextGeneral)
295
- c.tsw.WriteLiterally(")")
296
- } else {
297
- // Types match, just write the argument directly
298
- if err := c.WriteValueExpr(arg); err != nil {
299
- return fmt.Errorf("failed to write argument: %w", err)
300
- }
301
- }
302
- return nil
303
- }
304
-
305
- // For non-wrapper types, normal argument writing
306
- if err := c.WriteValueExpr(arg); err != nil {
307
- return fmt.Errorf("failed to write argument: %w", err)
308
- }
309
- return nil
310
- }
311
-
312
- // writeWrapperTypeMethodCall handles method calls on wrapper types by converting them to function calls
313
- // obj.Method(args) -> TypeName_Method(obj, args)
314
- func (c *GoToTSCompiler) writeWrapperTypeMethodCall(exp *ast.CallExpr, selectorExpr *ast.SelectorExpr) (handled bool, err error) {
315
- // Get the type of the base expression (the receiver)
316
- baseType := c.pkg.TypesInfo.TypeOf(selectorExpr.X)
317
- if baseType == nil {
318
- return false, nil
319
- }
320
-
321
- // Check if this is a wrapper type using the analysis
322
- if !c.isWrapperType(baseType) {
323
- return false, nil
324
- }
325
-
326
- // Get the qualified type name for the function call
327
- typeName := c.getQualifiedTypeName(baseType)
328
- if typeName == "" {
329
- return false, nil
330
- }
331
-
332
- // Write the function call: TypeName_MethodName(receiver, args...)
333
- c.tsw.WriteLiterally(typeName)
334
- c.tsw.WriteLiterally("_")
335
- c.tsw.WriteLiterally(selectorExpr.Sel.Name)
336
- c.tsw.WriteLiterally("(")
337
-
338
- // Write the receiver (the object the method is called on)
339
- // For pointer receiver methods, we need to pass the VarRef instead of the value
340
- receiverNeedsVarRef := false
341
-
342
- // Check if the method has a pointer receiver by looking at the method signature
343
- if selection := c.pkg.TypesInfo.Selections[selectorExpr]; selection != nil {
344
- if methodObj := selection.Obj(); methodObj != nil {
345
- if methodFunc, ok := methodObj.(*types.Func); ok {
346
- if sig, ok := methodFunc.Type().(*types.Signature); ok && sig != nil {
347
- if recv := sig.Recv(); recv != nil {
348
- if _, isPointer := recv.Type().(*types.Pointer); isPointer {
349
- receiverNeedsVarRef = true
350
- }
351
- }
352
- }
353
- }
354
- }
355
- }
356
-
357
- if receiverNeedsVarRef {
358
- // For pointer receivers, we need to pass the VarRef (not the value)
359
- // Check if the receiver expression is an identifier that's already a VarRef
360
- if ident, ok := selectorExpr.X.(*ast.Ident); ok {
361
- if obj := c.pkg.TypesInfo.ObjectOf(ident); obj != nil {
362
- if c.analysis != nil && c.analysis.NeedsVarRef(obj) {
363
- // This variable is already a VarRef, pass it directly
364
- c.tsw.WriteLiterally(ident.Name)
365
- } else {
366
- // Not a VarRef, write the value expression
367
- if err := c.WriteValueExpr(selectorExpr.X); err != nil {
368
- return true, fmt.Errorf("failed to write wrapper type method receiver: %w", err)
369
- }
370
- }
371
- } else {
372
- if err := c.WriteValueExpr(selectorExpr.X); err != nil {
373
- return true, fmt.Errorf("failed to write wrapper type method receiver: %w", err)
374
- }
375
- }
376
- } else if selExpr, ok := selectorExpr.X.(*ast.SelectorExpr); ok {
377
- // Convert p.field to p._fields.field for struct field access
378
- if baseIdent, ok := selExpr.X.(*ast.Ident); ok {
379
- c.tsw.WriteLiterally(baseIdent.Name)
380
- c.tsw.WriteLiterally("._fields.")
381
- c.tsw.WriteLiterally(selExpr.Sel.Name)
382
- } else {
383
- if err := c.WriteValueExpr(selectorExpr.X); err != nil {
384
- return true, fmt.Errorf("failed to write wrapper type method receiver: %w", err)
385
- }
386
- }
387
- } else {
388
- if err := c.WriteValueExpr(selectorExpr.X); err != nil {
389
- return true, fmt.Errorf("failed to write wrapper type method receiver: %w", err)
390
- }
391
- }
392
- } else {
393
- if err := c.WriteValueExpr(selectorExpr.X); err != nil {
394
- return true, fmt.Errorf("failed to write wrapper type method receiver: %w", err)
395
- }
396
- }
397
-
398
- // Add other arguments
399
- if len(exp.Args) > 0 {
400
- c.tsw.WriteLiterally(", ")
401
- for i, arg := range exp.Args {
402
- if i != 0 {
403
- c.tsw.WriteLiterally(", ")
404
- }
405
- if err := c.WriteValueExpr(arg); err != nil {
406
- return true, fmt.Errorf("failed to write wrapper type method argument %d: %w", i, err)
407
- }
408
- }
409
- }
410
-
411
- c.tsw.WriteLiterally(")")
412
- return true, nil
413
- }