goscript 0.0.75 → 0.0.77

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 (95) hide show
  1. package/cmd/goscript/main.js +48 -12
  2. package/compiler/analysis.go +100 -33
  3. package/compiler/analysis_test.go +2 -7
  4. package/compiler/assignment.go +34 -12
  5. package/compiler/code-writer.go +2 -2
  6. package/compiler/compiler.go +4 -4
  7. package/compiler/composite-lit.go +4 -6
  8. package/compiler/constraint.go +2 -4
  9. package/compiler/expr-call-async.go +4 -0
  10. package/compiler/expr-call-helpers.go +98 -8
  11. package/compiler/expr-call-make.go +4 -4
  12. package/compiler/expr-call.go +3 -0
  13. package/compiler/expr-type.go +42 -0
  14. package/compiler/gs_dependencies_test.go +3 -14
  15. package/compiler/index.ts +20 -5
  16. package/compiler/protobuf.go +21 -21
  17. package/compiler/spec-struct.go +22 -30
  18. package/compiler/spec.go +2 -2
  19. package/compiler/stmt-assign.go +2 -2
  20. package/compiler/type-info.go +20 -3
  21. package/compiler/type-utils.go +2 -4
  22. package/compiler/type.go +3 -4
  23. package/dist/compiler/index.js +13 -4
  24. package/dist/compiler/index.js.map +1 -1
  25. package/dist/gs/builtin/builtin.d.ts +6 -0
  26. package/dist/gs/builtin/builtin.js +26 -0
  27. package/dist/gs/builtin/builtin.js.map +1 -1
  28. package/dist/gs/builtin/slice.js +2 -3
  29. package/dist/gs/builtin/slice.js.map +1 -1
  30. package/dist/gs/builtin/type.d.ts +1 -0
  31. package/dist/gs/builtin/type.js +8 -14
  32. package/dist/gs/builtin/type.js.map +1 -1
  33. package/dist/gs/bytes/buffer.gs.d.ts +1 -0
  34. package/dist/gs/bytes/buffer.gs.js +20 -0
  35. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  36. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +5 -0
  37. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +10 -0
  38. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -0
  39. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.d.ts +50 -0
  40. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js +221 -0
  41. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -0
  42. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/index.d.ts +1 -0
  43. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/index.js +2 -0
  44. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/index.js.map +1 -0
  45. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/index.d.ts +1 -0
  46. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/index.js +2 -0
  47. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/index.js.map +1 -0
  48. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/runtime.d.ts +56 -0
  49. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/runtime.js +17 -0
  50. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/runtime.js.map +1 -0
  51. package/dist/gs/io/fs/format.js +2 -6
  52. package/dist/gs/io/fs/format.js.map +1 -1
  53. package/dist/gs/io/fs/glob.js +18 -23
  54. package/dist/gs/io/fs/glob.js.map +1 -1
  55. package/dist/gs/path/match.js +9 -22
  56. package/dist/gs/path/match.js.map +1 -1
  57. package/dist/gs/reflect/index.d.ts +1 -1
  58. package/dist/gs/reflect/index.js +1 -1
  59. package/dist/gs/reflect/index.js.map +1 -1
  60. package/dist/gs/reflect/type.d.ts +1 -0
  61. package/dist/gs/reflect/type.js +52 -23
  62. package/dist/gs/reflect/type.js.map +1 -1
  63. package/dist/gs/strings/iter.js +1 -1
  64. package/dist/gs/strings/iter.js.map +1 -1
  65. package/dist/gs/strings/reader.js +1 -1
  66. package/dist/gs/strings/reader.js.map +1 -1
  67. package/dist/gs/strings/replace.js +9 -20
  68. package/dist/gs/strings/replace.js.map +1 -1
  69. package/dist/gs/time/time.js +2 -2
  70. package/dist/gs/time/time.js.map +1 -1
  71. package/go.mod +9 -10
  72. package/go.sum +20 -22
  73. package/gs/builtin/builtin.ts +29 -0
  74. package/gs/builtin/slice.ts +2 -2
  75. package/gs/builtin/type.ts +14 -14
  76. package/gs/bytes/buffer.gs.ts +21 -1
  77. package/gs/fmt/fmt.test.ts +1 -1
  78. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +14 -0
  79. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +238 -0
  80. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/index.ts +1 -0
  81. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/meta.json +12 -0
  82. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/index.ts +1 -0
  83. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/meta.json +8 -0
  84. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/runtime.ts +94 -0
  85. package/gs/io/fs/format.ts +2 -5
  86. package/gs/io/fs/glob.ts +18 -21
  87. package/gs/path/match.ts +9 -22
  88. package/gs/reflect/index.ts +1 -0
  89. package/gs/reflect/type.ts +62 -25
  90. package/gs/strings/iter.ts +1 -1
  91. package/gs/strings/reader.ts +1 -1
  92. package/gs/strings/replace.ts +13 -18
  93. package/gs/time/time.ts +2 -2
  94. package/gs.go +8 -0
  95. package/package.json +20 -16
@@ -79,7 +79,7 @@ func (c *GoToTSCompiler) writeMakeSlice(sliceType *types.Slice, exp *ast.CallExp
79
79
 
80
80
  // Check if it's []byte
81
81
  if c.isByteSliceType(sliceType) {
82
- var lengthArg, capacityArg interface{}
82
+ var lengthArg, capacityArg any
83
83
  if len(exp.Args) >= 2 {
84
84
  lengthArg = exp.Args[1]
85
85
  }
@@ -90,7 +90,7 @@ func (c *GoToTSCompiler) writeMakeSlice(sliceType *types.Slice, exp *ast.CallExp
90
90
  }
91
91
 
92
92
  // Handle other slice types
93
- var lengthArg, capacityArg interface{}
93
+ var lengthArg, capacityArg any
94
94
  if len(exp.Args) >= 2 {
95
95
  lengthArg = exp.Args[1]
96
96
  }
@@ -193,7 +193,7 @@ func (c *GoToTSCompiler) WriteCallExprMake(exp *ast.CallExpr) error {
193
193
  if elemType != nil {
194
194
  // Check if it's make(S, ...) where S constrains to []byte
195
195
  if c.isByteSliceType(types.NewSlice(elemType)) {
196
- var lengthArg, capacityArg interface{}
196
+ var lengthArg, capacityArg any
197
197
  if len(exp.Args) >= 2 {
198
198
  lengthArg = exp.Args[1]
199
199
  }
@@ -203,7 +203,7 @@ func (c *GoToTSCompiler) WriteCallExprMake(exp *ast.CallExpr) error {
203
203
  return c.writeByteSliceCreation(lengthArg, capacityArg)
204
204
  }
205
205
 
206
- var lengthArg, capacityArg interface{}
206
+ var lengthArg, capacityArg any
207
207
  if len(exp.Args) >= 2 {
208
208
  lengthArg = exp.Args[1]
209
209
  }
@@ -100,6 +100,9 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
100
100
  // Handle reflect.TypeFor[T]() - Fun is IndexExpr where X is SelectorExpr
101
101
  if indexExpr, ok := expFun.(*ast.IndexExpr); ok {
102
102
  if selectorExpr, ok := indexExpr.X.(*ast.SelectorExpr); ok {
103
+ if handled, err := c.writeReflectTypeAssert(exp, selectorExpr); handled {
104
+ return err
105
+ }
103
106
  if handled, err := c.writeReflectTypeFor(exp, selectorExpr); handled {
104
107
  return err
105
108
  }
@@ -20,6 +20,48 @@ import (
20
20
  // - Interface types -> TypeScript interface types or "any"
21
21
  // - Function types -> TypeScript function signatures
22
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
+
23
65
  // Handle selector expressions (e.g., os.FileInfo) specially to preserve qualified names
24
66
  if selectorExpr, ok := a.(*ast.SelectorExpr); ok {
25
67
  if pkgIdent, ok := selectorExpr.X.(*ast.Ident); ok {
@@ -1,6 +1,7 @@
1
1
  package compiler
2
2
 
3
3
  import (
4
+ "slices"
4
5
  "testing"
5
6
 
6
7
  "github.com/sirupsen/logrus"
@@ -36,13 +37,7 @@ func TestReadGsPackageMetadata(t *testing.T) {
36
37
  }
37
38
 
38
39
  // Check for the specific "iter" dependency
39
- foundIter := false
40
- for _, dep := range metadata.Dependencies {
41
- if dep == "iter" {
42
- foundIter = true
43
- break
44
- }
45
- }
40
+ foundIter := slices.Contains(metadata.Dependencies, "iter")
46
41
 
47
42
  if !foundIter {
48
43
  t.Errorf("Expected to find 'iter' dependency, got dependencies: %v", metadata.Dependencies)
@@ -51,13 +46,7 @@ func TestReadGsPackageMetadata(t *testing.T) {
51
46
  // Also check for other expected dependencies from the bytes package
52
47
  expectedDeps := []string{"errors", "io", "iter", "unicode", "unicode/utf8", "unsafe"}
53
48
  for _, expected := range expectedDeps {
54
- found := false
55
- for _, dep := range metadata.Dependencies {
56
- if dep == expected {
57
- found = true
58
- break
59
- }
60
- }
49
+ found := slices.Contains(metadata.Dependencies, expected)
61
50
  if !found {
62
51
  t.Errorf("Expected to find dependency '%s', got dependencies: %v", expected, metadata.Dependencies)
63
52
  }
package/compiler/index.ts CHANGED
@@ -65,15 +65,30 @@ export async function compile(config: CompileConfig): Promise<void> {
65
65
  // Go compiler often prints status messages to stderr, treat as info unless exit code is non-zero
66
66
  console.info(`GoScript stderr:\n${stderr}`);
67
67
  }
68
- } catch (error: any) {
69
- console.error(`GoScript compilation failed: ${error.message}`);
70
- if (error.stderr) {
68
+ } catch (error: unknown) {
69
+ const compileErr =
70
+ error instanceof Error ? error : new Error(String(error));
71
+
72
+ console.error(`GoScript compilation failed: ${compileErr.message}`);
73
+ if (
74
+ typeof error === "object" &&
75
+ error !== null &&
76
+ "stderr" in error &&
77
+ typeof error.stderr === "string"
78
+ ) {
71
79
  console.error(`GoScript stderr:\n${error.stderr}`);
72
80
  }
73
- if (error.stdout) {
81
+ if (
82
+ typeof error === "object" &&
83
+ error !== null &&
84
+ "stdout" in error &&
85
+ typeof error.stdout === "string"
86
+ ) {
74
87
  console.error(`GoScript stdout:\n${error.stdout}`);
75
88
  }
76
- throw new Error(`GoScript compilation failed: ${error.message}`);
89
+ throw new Error(`GoScript compilation failed: ${compileErr.message}`, {
90
+ cause: error,
91
+ });
77
92
  }
78
93
  }
79
94
 
@@ -146,35 +146,35 @@ func (c *PackageCompiler) writeProtobufExports(indexFile *os.File, fileName stri
146
146
  // - export function Name
147
147
  // We avoid type-only exports for now.
148
148
  var exports []string
149
- lines := strings.Split(string(content), "\n")
150
- for _, ln := range lines {
149
+ lines := strings.SplitSeq(string(content), "\n")
150
+ for ln := range lines {
151
151
  l := strings.TrimSpace(ln)
152
- if strings.HasPrefix(l, "export const ") {
153
- rest := strings.TrimPrefix(l, "export const ")
152
+ if after, ok := strings.CutPrefix(l, "export const "); ok {
153
+ rest := after
154
154
  name := takeIdent(rest)
155
155
  if name != "" {
156
156
  exports = append(exports, name)
157
157
  }
158
158
  continue
159
159
  }
160
- if strings.HasPrefix(l, "export interface ") {
161
- rest := strings.TrimPrefix(l, "export interface ")
160
+ if after, ok := strings.CutPrefix(l, "export interface "); ok {
161
+ rest := after
162
162
  name := takeIdent(rest)
163
163
  if name != "" {
164
164
  exports = append(exports, name)
165
165
  }
166
166
  continue
167
167
  }
168
- if strings.HasPrefix(l, "export class ") {
169
- rest := strings.TrimPrefix(l, "export class ")
168
+ if after, ok := strings.CutPrefix(l, "export class "); ok {
169
+ rest := after
170
170
  name := takeIdent(rest)
171
171
  if name != "" {
172
172
  exports = append(exports, name)
173
173
  }
174
174
  continue
175
175
  }
176
- if strings.HasPrefix(l, "export function ") {
177
- rest := strings.TrimPrefix(l, "export function ")
176
+ if after, ok := strings.CutPrefix(l, "export function "); ok {
177
+ rest := after
178
178
  name := takeIdent(rest)
179
179
  if name != "" {
180
180
  exports = append(exports, name)
@@ -236,9 +236,9 @@ func (c *FileCompiler) addProtobufImports() error {
236
236
 
237
237
  for _, fileName := range c.pkg.CompiledGoFiles {
238
238
  baseFileName := filepath.Base(fileName)
239
- if strings.HasSuffix(baseFileName, ".pb.go") {
239
+ if before, ok := strings.CutSuffix(baseFileName, ".pb.go"); ok {
240
240
  // Check if there's a corresponding .pb.ts file
241
- pbTsFileName := strings.TrimSuffix(baseFileName, ".pb.go") + ".pb.ts"
241
+ pbTsFileName := before + ".pb.ts"
242
242
  pbTsPath := filepath.Join(packageDir, pbTsFileName)
243
243
 
244
244
  if _, err := os.Stat(pbTsPath); err == nil {
@@ -252,28 +252,28 @@ func (c *FileCompiler) addProtobufImports() error {
252
252
 
253
253
  // Discover exported identifiers (const/interface/class/function)
254
254
  var exports []string
255
- for _, ln := range strings.Split(string(content), "\n") {
255
+ for ln := range strings.SplitSeq(string(content), "\n") {
256
256
  l := strings.TrimSpace(ln)
257
- if strings.HasPrefix(l, "export const ") {
258
- if name := takeIdent(strings.TrimPrefix(l, "export const ")); name != "" {
257
+ if after, ok := strings.CutPrefix(l, "export const "); ok {
258
+ if name := takeIdent(after); name != "" {
259
259
  exports = append(exports, name)
260
260
  }
261
261
  continue
262
262
  }
263
- if strings.HasPrefix(l, "export interface ") {
264
- if name := takeIdent(strings.TrimPrefix(l, "export interface ")); name != "" {
263
+ if after, ok := strings.CutPrefix(l, "export interface "); ok {
264
+ if name := takeIdent(after); name != "" {
265
265
  exports = append(exports, name)
266
266
  }
267
267
  continue
268
268
  }
269
- if strings.HasPrefix(l, "export class ") {
270
- if name := takeIdent(strings.TrimPrefix(l, "export class ")); name != "" {
269
+ if after, ok := strings.CutPrefix(l, "export class "); ok {
270
+ if name := takeIdent(after); name != "" {
271
271
  exports = append(exports, name)
272
272
  }
273
273
  continue
274
274
  }
275
- if strings.HasPrefix(l, "export function ") {
276
- if name := takeIdent(strings.TrimPrefix(l, "export function ")); name != "" {
275
+ if after, ok := strings.CutPrefix(l, "export function "); ok {
276
+ if name := takeIdent(after); name != "" {
277
277
  exports = append(exports, name)
278
278
  }
279
279
  continue
@@ -4,6 +4,7 @@ import (
4
4
  "fmt"
5
5
  "go/ast"
6
6
  "go/types"
7
+ "maps"
7
8
  "slices"
8
9
  "strings"
9
10
  )
@@ -72,8 +73,7 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
72
73
  }
73
74
 
74
75
  // Generate getters and setters for EMBEDDED struct fields themselves
75
- for i := range underlyingStruct.NumFields() {
76
- field := underlyingStruct.Field(i)
76
+ for field := range underlyingStruct.Fields() {
77
77
  if field.Anonymous() {
78
78
  fieldKeyName := c.getEmbeddedFieldKeyName(field.Type())
79
79
  c.writeGetterSetter(fieldKeyName, field.Type(), nil, nil, nil)
@@ -95,8 +95,7 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
95
95
  c.tsw.Indent(1)
96
96
  c.tsw.WriteLine("")
97
97
 
98
- for i := 0; i < underlyingStruct.NumFields(); i++ {
99
- field := underlyingStruct.Field(i)
98
+ for field := range underlyingStruct.Fields() {
100
99
  var fieldKeyName string
101
100
  if field.Anonymous() {
102
101
  fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
@@ -166,25 +165,26 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
166
165
  c.tsw.WriteLine("")
167
166
 
168
167
  // Generate the clone method
169
- cloneReturnType := className
168
+ var cloneReturnType strings.Builder
169
+ cloneReturnType.WriteString(className)
170
170
  if a.TypeParams != nil && len(a.TypeParams.List) > 0 {
171
- cloneReturnType += "<"
171
+ cloneReturnType.WriteString("<")
172
172
  first := true
173
173
  for _, field := range a.TypeParams.List {
174
174
  for _, name := range field.Names {
175
175
  if !first {
176
- cloneReturnType += ", "
176
+ cloneReturnType.WriteString(", ")
177
177
  }
178
178
  first = false
179
- cloneReturnType += name.Name
179
+ cloneReturnType.WriteString(name.Name)
180
180
  }
181
181
  }
182
- cloneReturnType += ">"
182
+ cloneReturnType.WriteString(">")
183
183
  }
184
184
 
185
- c.tsw.WriteLinef("public clone(): %s {", cloneReturnType)
185
+ c.tsw.WriteLinef("public clone(): %s {", cloneReturnType.String())
186
186
  c.tsw.Indent(1)
187
- c.tsw.WriteLinef("const cloned = new %s()", cloneReturnType)
187
+ c.tsw.WriteLinef("const cloned = new %s()", cloneReturnType.String())
188
188
  c.tsw.WriteLine("cloned._fields = {")
189
189
  c.tsw.Indent(1)
190
190
 
@@ -257,8 +257,7 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
257
257
  seenPromotedFields := make(map[string]bool)
258
258
  directMethods := make(map[string]bool)
259
259
  // Populate directMethods (methods defined directly on this struct type)
260
- for i := range goStructType.NumMethods() {
261
- method := goStructType.Method(i)
260
+ for method := range goStructType.Methods() {
262
261
  sig := method.Type().(*types.Signature)
263
262
  if sig.Recv() != nil {
264
263
  recvType := sig.Recv().Type()
@@ -272,8 +271,7 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
272
271
  }
273
272
  }
274
273
 
275
- for i := range underlyingStruct.NumFields() {
276
- field := underlyingStruct.Field(i)
274
+ for field := range underlyingStruct.Fields() {
277
275
  if !field.Anonymous() {
278
276
  continue
279
277
  }
@@ -293,8 +291,7 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
293
291
  // Promoted fields
294
292
  if namedEmbedded, ok := trueEmbeddedType.(*types.Named); ok {
295
293
  if underlyingEmbeddedStruct, ok := namedEmbedded.Underlying().(*types.Struct); ok {
296
- for j := 0; j < underlyingEmbeddedStruct.NumFields(); j++ {
297
- promotedField := underlyingEmbeddedStruct.Field(j)
294
+ for promotedField := range underlyingEmbeddedStruct.Fields() {
298
295
  if !promotedField.Exported() && promotedField.Pkg() != c.pkg.Types {
299
296
  continue
300
297
  }
@@ -304,8 +301,8 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
304
301
  }
305
302
  // Check for conflicts with outer struct's own fields or other promoted fields
306
303
  conflict := false
307
- for k := 0; k < underlyingStruct.NumFields(); k++ {
308
- if !underlyingStruct.Field(k).Anonymous() && underlyingStruct.Field(k).Name() == promotedFieldName {
304
+ for field := range underlyingStruct.Fields() {
305
+ if !field.Anonymous() && field.Name() == promotedFieldName {
309
306
  conflict = true
310
307
  break
311
308
  }
@@ -358,8 +355,7 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
358
355
  }
359
356
  }
360
357
  embeddedMethodSet := types.NewMethodSet(methodSetType)
361
- for k := range embeddedMethodSet.Len() {
362
- methodSelection := embeddedMethodSet.At(k)
358
+ for methodSelection := range embeddedMethodSet.Methods() {
363
359
  method := methodSelection.Obj().(*types.Func)
364
360
  methodName := method.Name()
365
361
 
@@ -367,8 +363,8 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
367
363
  if len(methodSelection.Index()) == 1 && !directMethods[methodName] && !seenPromotedFields[methodName] {
368
364
  // Check for conflict with outer struct's own fields
369
365
  conflictWithField := false
370
- for k_idx := 0; k_idx < underlyingStruct.NumFields(); k_idx++ {
371
- if !underlyingStruct.Field(k_idx).Anonymous() && underlyingStruct.Field(k_idx).Name() == methodName {
366
+ for field := range underlyingStruct.Fields() {
367
+ if !field.Anonymous() && field.Name() == methodName {
372
368
  conflictWithField = true
373
369
  break
374
370
  }
@@ -457,8 +453,7 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
457
453
  c.tsw.WriteLiterally(" [")
458
454
  // Collect methods for the struct type
459
455
  var structMethods []*types.Func
460
- for i := range goStructType.NumMethods() {
461
- method := goStructType.Method(i)
456
+ for method := range goStructType.Methods() {
462
457
  // Ensure it's a method directly on this type (not promoted here, promotion handled separately)
463
458
  // Check if receiver is *T or T where T is goStructType
464
459
  sig := method.Type().(*types.Signature)
@@ -545,8 +540,7 @@ func (c *GoToTSCompiler) generateFlattenedInitTypeString(structType *types.Named
545
540
  }
546
541
 
547
542
  // First add the direct fields and track embedded types
548
- for i := 0; i < underlying.NumFields(); i++ {
549
- field := underlying.Field(i)
543
+ for field := range underlying.Fields() {
550
544
  fieldName := field.Name()
551
545
 
552
546
  // Skip underscore fields
@@ -587,9 +581,7 @@ func (c *GoToTSCompiler) generateFlattenedInitTypeString(structType *types.Named
587
581
  // not typically set directly in `init?` unless the embedded struct itself is named in `init?`.
588
582
 
589
583
  // Add embedded types to the field map (these are the names of the embedded structs themselves)
590
- for embeddedName, embeddedTSType := range embeddedTypeMap {
591
- fieldMap[embeddedName] = embeddedTSType
592
- }
584
+ maps.Copy(fieldMap, embeddedTypeMap)
593
585
 
594
586
  var fieldNames []string
595
587
  for name := range fieldMap {
package/compiler/spec.go CHANGED
@@ -560,8 +560,8 @@ func (c *GoToTSCompiler) WriteInterfaceTypeSpec(a *ast.TypeSpec, t *ast.Interfac
560
560
  // Collect methods for the interface type
561
561
  var interfaceMethods []*types.Func
562
562
  if ifaceType != nil { // ifaceType is *types.Interface
563
- for i := range ifaceType.NumExplicitMethods() {
564
- interfaceMethods = append(interfaceMethods, ifaceType.ExplicitMethod(i))
563
+ for method := range ifaceType.ExplicitMethods() {
564
+ interfaceMethods = append(interfaceMethods, method)
565
565
  }
566
566
  // TODO: Handle embedded interface methods if necessary for full signature collection.
567
567
  // For now, explicit methods are covered.
@@ -313,8 +313,8 @@ func (c *GoToTSCompiler) writeMultiVarAssignFromCall(lhs []ast.Expr, callExpr *a
313
313
  if funType := c.pkg.TypesInfo.TypeOf(callExpr.Fun); funType != nil {
314
314
  if funcType, ok := funType.Underlying().(*types.Signature); ok {
315
315
  if funcType.Results() != nil && funcType.Results().Len() > 0 {
316
- for i := 0; i < funcType.Results().Len(); i++ {
317
- resultTypes = append(resultTypes, funcType.Results().At(i))
316
+ for v := range funcType.Results().Variables() {
317
+ resultTypes = append(resultTypes, v)
318
318
  }
319
319
  }
320
320
  }
@@ -2,6 +2,23 @@ package compiler
2
2
 
3
3
  import "go/types"
4
4
 
5
+ func qualifiedTypeName(namedType *types.Named) string {
6
+ if namedType == nil || namedType.Obj() == nil {
7
+ return ""
8
+ }
9
+
10
+ typeName := namedType.Obj().Name()
11
+ if pkg := namedType.Obj().Pkg(); pkg != nil {
12
+ switch {
13
+ case pkg.Name() == "main":
14
+ typeName = "main." + typeName
15
+ case pkg.Path() != "":
16
+ typeName = pkg.Path() + "." + typeName
17
+ }
18
+ }
19
+ return typeName
20
+ }
21
+
5
22
  // writeTypeInfoObject writes a TypeScript TypeInfo object literal for a given Go type.
6
23
  func (c *GoToTSCompiler) writeTypeInfoObject(typ types.Type) {
7
24
  if typ == nil {
@@ -17,7 +34,7 @@ func (c *GoToTSCompiler) writeTypeInfoObject(typ types.Type) {
17
34
  // For all other named types, output their name as a string literal.
18
35
  // This relies on the type being registered elsewhere (e.g., via registerStructType or registerInterfaceType)
19
36
  // so the TypeScript runtime can resolve the reference.
20
- c.tsw.WriteLiterallyf("%q", namedType.Obj().Name())
37
+ c.tsw.WriteLiterallyf("%q", qualifiedTypeName(namedType))
21
38
  }
22
39
  return // Return after handling the named type by reference.
23
40
  }
@@ -64,8 +81,8 @@ func (c *GoToTSCompiler) writeTypeInfoObject(typ types.Type) {
64
81
  case *types.Interface: // Anonymous interface or underlying of a non-named type alias
65
82
  c.tsw.WriteLiterally("{ kind: $.TypeKind.Interface, methods: [")
66
83
  var methods []*types.Func
67
- for i := 0; i < t.NumExplicitMethods(); i++ {
68
- methods = append(methods, t.ExplicitMethod(i))
84
+ for method := range t.ExplicitMethods() {
85
+ methods = append(methods, method)
69
86
  }
70
87
  // TODO: Handle embedded methods for anonymous interfaces if needed.
71
88
  c.writeMethodSignatures(methods) // Calls writeMethodSignatures -> writeTypeInfoObject
@@ -47,12 +47,10 @@ func (c *GoToTSCompiler) constraintIncludesString(constraint *types.Interface) b
47
47
  return false // Pure method interface, no type terms
48
48
  }
49
49
  // For union constraints like []byte | string, check each term
50
- for i := 0; i < constraint.NumEmbeddeds(); i++ {
51
- embedded := constraint.EmbeddedType(i)
50
+ for embedded := range constraint.EmbeddedTypes() {
52
51
  // Check if embedded is a union
53
52
  if union, isUnion := embedded.(*types.Union); isUnion {
54
- for j := 0; j < union.Len(); j++ {
55
- term := union.Term(j)
53
+ for term := range union.Terms() {
56
54
  termType := term.Type()
57
55
  // Check if term is string or ~string
58
56
  if basic, isBasic := termType.Underlying().(*types.Basic); isBasic {
package/compiler/type.go CHANGED
@@ -605,8 +605,7 @@ func (c *GoToTSCompiler) writeInterfaceStructure(iface *types.Interface, astNode
605
605
  c.tsw.Indent(1)
606
606
  c.tsw.WriteLine("") // Newline after opening brace, before the first method
607
607
 
608
- for i := 0; i < iface.NumExplicitMethods(); i++ {
609
- method := iface.ExplicitMethod(i)
608
+ for method := range iface.ExplicitMethods() {
610
609
  sig := method.Type().(*types.Signature)
611
610
 
612
611
  // Find corresponding ast.Field for comments if astNode is available
@@ -745,14 +744,14 @@ func (c *GoToTSCompiler) writeInterfaceStructure(iface *types.Interface, astNode
745
744
 
746
745
  // Handle embedded types
747
746
  if iface.NumEmbeddeds() > 0 {
748
- for i := 0; i < iface.NumEmbeddeds(); i++ {
747
+ for etyp := range iface.EmbeddedTypes() {
749
748
  if firstPartWritten {
750
749
  c.tsw.WriteLiterally(" & ")
751
750
  } else {
752
751
  // This is the first part being written (no explicit methods, only embedded)
753
752
  firstPartWritten = true
754
753
  }
755
- embeddedType := iface.EmbeddedType(i)
754
+ embeddedType := etyp
756
755
  // When WriteGoType encounters an interface, it will call WriteInterfaceType
757
756
  // which will pass nil for astNode, so comments for deeply embedded interface literals
758
757
  // might not be available unless they are named types.
@@ -45,14 +45,23 @@ export async function compile(config) {
45
45
  }
46
46
  }
47
47
  catch (error) {
48
- console.error(`GoScript compilation failed: ${error.message}`);
49
- if (error.stderr) {
48
+ const compileErr = error instanceof Error ? error : new Error(String(error));
49
+ console.error(`GoScript compilation failed: ${compileErr.message}`);
50
+ if (typeof error === "object" &&
51
+ error !== null &&
52
+ "stderr" in error &&
53
+ typeof error.stderr === "string") {
50
54
  console.error(`GoScript stderr:\n${error.stderr}`);
51
55
  }
52
- if (error.stdout) {
56
+ if (typeof error === "object" &&
57
+ error !== null &&
58
+ "stdout" in error &&
59
+ typeof error.stdout === "string") {
53
60
  console.error(`GoScript stdout:\n${error.stdout}`);
54
61
  }
55
- throw new Error(`GoScript compilation failed: ${error.message}`);
62
+ throw new Error(`GoScript compilation failed: ${compileErr.message}`, {
63
+ cause: error,
64
+ });
56
65
  }
57
66
  }
58
67
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../compiler/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../compiler/index.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,12 @@ export declare function panic(...args: any[]): never;
16
16
  * @param v The slice or map to clear
17
17
  */
18
18
  export declare function clear<T>(v: T[] | Map<unknown, unknown> | null): void;
19
+ /**
20
+ * assignStruct copies all field values from source struct to target struct.
21
+ * Used for pointer dereference assignment: *p = value
22
+ * Copies the _fields contents from source to target.
23
+ */
24
+ export declare function assignStruct<T>(target: T, source: T): void;
19
25
  export type Bytes = Uint8Array | Slice<number>;
20
26
  export declare function int(value: number): number;
21
27
  /**
@@ -38,6 +38,32 @@ export function clear(v) {
38
38
  return;
39
39
  }
40
40
  }
41
+ /**
42
+ * assignStruct copies all field values from source struct to target struct.
43
+ * Used for pointer dereference assignment: *p = value
44
+ * Copies the _fields contents from source to target.
45
+ */
46
+ export function assignStruct(target, source) {
47
+ if (target === null ||
48
+ target === undefined ||
49
+ source === null ||
50
+ source === undefined) {
51
+ return;
52
+ }
53
+ const targetFields = target._fields;
54
+ const sourceFields = source._fields;
55
+ if (!targetFields || !sourceFields) {
56
+ return;
57
+ }
58
+ // Copy each field's value from source to target
59
+ for (const key of Object.keys(sourceFields)) {
60
+ const sourceField = sourceFields[key];
61
+ const targetField = targetFields[key];
62
+ if (sourceField && targetField && sourceField.value !== undefined) {
63
+ targetField.value = sourceField.value;
64
+ }
65
+ }
66
+ }
41
67
  // int converts a value to a Go int type, handling proper signed integer conversion
42
68
  // This ensures that values like 2147483648 (2^31) are properly handled according to Go semantics
43
69
  export function int(value) {