goscript 0.0.23 → 0.0.25

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 (94) hide show
  1. package/README.md +2 -2
  2. package/cmd/goscript/cmd_compile.go +18 -2
  3. package/compiler/analysis.go +74 -132
  4. package/compiler/analysis_test.go +220 -0
  5. package/compiler/assignment.go +37 -43
  6. package/compiler/builtin_test.go +90 -0
  7. package/compiler/compiler.go +307 -22
  8. package/compiler/composite-lit.go +108 -43
  9. package/compiler/config.go +7 -3
  10. package/compiler/config_test.go +6 -33
  11. package/compiler/decl.go +7 -1
  12. package/compiler/expr-call.go +212 -2
  13. package/compiler/expr-selector.go +66 -41
  14. package/compiler/expr-star.go +57 -65
  15. package/compiler/expr-type.go +1 -1
  16. package/compiler/expr-value.go +1 -1
  17. package/compiler/expr.go +125 -20
  18. package/compiler/field.go +4 -4
  19. package/compiler/primitive.go +11 -10
  20. package/compiler/spec-struct.go +3 -3
  21. package/compiler/spec-value.go +75 -29
  22. package/compiler/spec.go +9 -3
  23. package/compiler/stmt-assign.go +36 -2
  24. package/compiler/stmt-for.go +11 -0
  25. package/compiler/stmt-range.go +314 -1
  26. package/compiler/stmt.go +52 -0
  27. package/compiler/type.go +83 -15
  28. package/dist/gs/builtin/builtin.d.ts +9 -0
  29. package/dist/gs/builtin/builtin.js +46 -0
  30. package/dist/gs/builtin/builtin.js.map +1 -0
  31. package/dist/gs/builtin/channel.d.ts +193 -0
  32. package/dist/gs/builtin/channel.js +471 -0
  33. package/dist/gs/builtin/channel.js.map +1 -0
  34. package/dist/gs/builtin/defer.d.ts +38 -0
  35. package/dist/gs/builtin/defer.js +54 -0
  36. package/dist/gs/builtin/defer.js.map +1 -0
  37. package/dist/gs/builtin/index.d.ts +1 -0
  38. package/dist/gs/builtin/index.js +2 -0
  39. package/dist/gs/builtin/index.js.map +1 -0
  40. package/dist/gs/builtin/io.d.ts +16 -0
  41. package/dist/gs/builtin/io.js +15 -0
  42. package/dist/gs/builtin/io.js.map +1 -0
  43. package/dist/gs/builtin/map.d.ts +33 -0
  44. package/dist/gs/builtin/map.js +44 -0
  45. package/dist/gs/builtin/map.js.map +1 -0
  46. package/dist/gs/builtin/slice.d.ts +173 -0
  47. package/dist/gs/builtin/slice.js +799 -0
  48. package/dist/gs/builtin/slice.js.map +1 -0
  49. package/dist/gs/builtin/type.d.ts +203 -0
  50. package/dist/gs/builtin/type.js +744 -0
  51. package/dist/gs/builtin/type.js.map +1 -0
  52. package/dist/gs/builtin/varRef.d.ts +14 -0
  53. package/dist/gs/builtin/varRef.js +14 -0
  54. package/dist/gs/builtin/varRef.js.map +1 -0
  55. package/dist/gs/cmp/index.d.ts +4 -0
  56. package/dist/gs/cmp/index.js +27 -0
  57. package/dist/gs/cmp/index.js.map +1 -0
  58. package/dist/gs/context/context.d.ts +26 -0
  59. package/dist/gs/context/context.js +305 -0
  60. package/dist/gs/context/context.js.map +1 -0
  61. package/dist/gs/context/index.d.ts +1 -0
  62. package/dist/gs/context/index.js +2 -0
  63. package/dist/gs/context/index.js.map +1 -0
  64. package/dist/gs/internal/goarch/index.d.ts +6 -0
  65. package/dist/gs/internal/goarch/index.js +14 -0
  66. package/dist/gs/internal/goarch/index.js.map +1 -0
  67. package/dist/gs/iter/index.d.ts +1 -0
  68. package/dist/gs/iter/index.js +2 -0
  69. package/dist/gs/iter/index.js.map +1 -0
  70. package/dist/gs/iter/iter.d.ts +4 -0
  71. package/dist/gs/iter/iter.js +91 -0
  72. package/dist/gs/iter/iter.js.map +1 -0
  73. package/dist/gs/math/bits/index.d.ts +47 -0
  74. package/dist/gs/math/bits/index.js +298 -0
  75. package/dist/gs/math/bits/index.js.map +1 -0
  76. package/dist/gs/runtime/index.d.ts +1 -0
  77. package/dist/gs/runtime/index.js +2 -0
  78. package/dist/gs/runtime/index.js.map +1 -0
  79. package/dist/gs/runtime/runtime.d.ts +41 -0
  80. package/dist/gs/runtime/runtime.js +158 -0
  81. package/dist/gs/runtime/runtime.js.map +1 -0
  82. package/dist/gs/slices/index.d.ts +1 -0
  83. package/dist/gs/slices/index.js +2 -0
  84. package/dist/gs/slices/index.js.map +1 -0
  85. package/dist/gs/slices/slices.d.ts +8 -0
  86. package/dist/gs/slices/slices.js +20 -0
  87. package/dist/gs/slices/slices.js.map +1 -0
  88. package/dist/gs/time/index.d.ts +1 -0
  89. package/dist/gs/time/index.js +2 -0
  90. package/dist/gs/time/index.js.map +1 -0
  91. package/dist/gs/time/time.d.ts +57 -0
  92. package/dist/gs/time/time.js +208 -0
  93. package/dist/gs/time/time.js.map +1 -0
  94. package/package.json +3 -2
@@ -21,7 +21,7 @@ import (
21
21
  // to `$.mapSet(myMap_ts, key_ts, value_ts)`.
22
22
  // - Other single-variable assignments (`variable = value`):
23
23
  // - The LHS expression is written (caller typically ensures `.value` is appended
24
- // if assigning to a boxed variable's content).
24
+ // if assigning to a VarRefed variable's content).
25
25
  // - The Go assignment token (`tok`, e.g., `=`, `+=`) is translated to its
26
26
  // TypeScript equivalent using `TokenToTs`.
27
27
  // - The RHS expression(s) are written. If `shouldApplyClone` indicates the RHS
@@ -68,10 +68,10 @@ func (c *GoToTSCompiler) writeAssignmentCore(lhs, rhs []ast.Expr, tok token.Toke
68
68
  return nil
69
69
  }
70
70
 
71
- // Special handling for boxed variables in declarations
71
+ // Special handling for variable referenced variables in declarations
72
72
  if addDeclaration && tok == token.DEFINE {
73
- // Determine if LHS is boxed
74
- isLHSBoxed := false
73
+ // Determine if LHS is variable referenced
74
+ isLHSVarRefed := false
75
75
  var lhsIdent *ast.Ident
76
76
  var lhsObj types.Object
77
77
 
@@ -84,30 +84,22 @@ func (c *GoToTSCompiler) writeAssignmentCore(lhs, rhs []ast.Expr, tok token.Toke
84
84
  lhsObj = def
85
85
  }
86
86
 
87
- // Check if this variable needs to be boxed
88
- if lhsObj != nil && c.analysis.NeedsBoxed(lhsObj) {
89
- isLHSBoxed = true
87
+ // Check if this variable needs to be variable referenced
88
+ if lhsObj != nil && c.analysis.NeedsVarRef(lhsObj) {
89
+ isLHSVarRefed = true
90
90
  }
91
91
  }
92
92
 
93
- // Special handling for short declaration of boxed variables
94
- if isLHSBoxed && lhsIdent != nil {
93
+ // Special handling for short declaration of variable referenced variables
94
+ if isLHSVarRefed && lhsIdent != nil {
95
95
  c.tsw.WriteLiterally("let ")
96
96
  // Just write the identifier name without .value
97
97
  c.tsw.WriteLiterally(lhsIdent.Name)
98
-
99
- // Add type annotation for boxed variables in declarations
100
- if lhsObj != nil {
101
- c.tsw.WriteLiterally(": ")
102
- c.tsw.WriteLiterally("$.Box<")
103
- c.WriteGoType(lhsObj.Type(), GoTypeContextGeneral)
104
- c.tsw.WriteLiterally(">")
105
- }
106
-
98
+ // No type annotation, allow TypeScript to infer it from varRef.
107
99
  c.tsw.WriteLiterally(" = ")
108
100
 
109
- // Box the initializer
110
- c.tsw.WriteLiterally("$.box(")
101
+ // Create the variable reference for the initializer
102
+ c.tsw.WriteLiterally("$.varRef(")
111
103
  if err := c.WriteValueExpr(rhs[0]); err != nil {
112
104
  return err
113
105
  }
@@ -226,12 +218,12 @@ func (c *GoToTSCompiler) writeAssignmentCore(lhs, rhs []ast.Expr, tok token.Toke
226
218
  }
227
219
 
228
220
  if !currentIsMapIndex {
229
- // For single assignments, handle boxed variables specially
221
+ // For single assignments, handle variable referenced variables specially
230
222
  if len(lhs) == 1 && len(rhs) == 1 {
231
223
  lhsExprIdent, lhsExprIsIdent := l.(*ast.Ident)
232
224
  if lhsExprIsIdent {
233
- // Determine if LHS is boxed
234
- isLHSBoxed := false
225
+ // Determine if LHS is variable referenced
226
+ isLHSVarRefed := false
235
227
  var lhsObj types.Object
236
228
 
237
229
  // Get the types.Object from the identifier
@@ -241,13 +233,13 @@ func (c *GoToTSCompiler) writeAssignmentCore(lhs, rhs []ast.Expr, tok token.Toke
241
233
  lhsObj = def
242
234
  }
243
235
 
244
- // Check if this variable needs to be boxed
245
- if lhsObj != nil && c.analysis.NeedsBoxed(lhsObj) {
246
- isLHSBoxed = true
236
+ // Check if this variable needs to be variable referenced
237
+ if lhsObj != nil && c.analysis.NeedsVarRef(lhsObj) {
238
+ isLHSVarRefed = true
247
239
  }
248
240
 
249
- // prevent writing .value unless lhs is boxed
250
- c.WriteIdent(lhsExprIdent, isLHSBoxed)
241
+ // prevent writing .value unless lhs is variable referenced
242
+ c.WriteIdent(lhsExprIdent, isLHSVarRefed)
251
243
  continue
252
244
  }
253
245
  }
@@ -279,15 +271,16 @@ func (c *GoToTSCompiler) writeAssignmentCore(lhs, rhs []ast.Expr, tok token.Toke
279
271
  if i != 0 {
280
272
  c.tsw.WriteLiterally(", ")
281
273
  }
282
- // Check if we need to access a boxed source value and apply clone
274
+
275
+ // Check if we need to access a variable referenced source value and apply clone
283
276
  // For struct value assignments, we need to handle:
284
- // 1. Unboxed source, unboxed target: source.clone()
285
- // 2. Boxed source, unboxed target: source.value.clone()
286
- // 3. Unboxed source, boxed target: $.box(source)
287
- // 4. Boxed source, boxed target: source (straight assignment of the box)
277
+ // 1. UnVarRefed source, unVarRefed target: source.clone()
278
+ // 2. Variable referenced source, unVarRefed target: source.value.clone()
279
+ // 3. UnVarRefed source, variable referenced target: $.varRef(source)
280
+ // 4. Variable referenced source, variable referenced target: source (straight assignment of the variable reference)
288
281
 
289
- // Determine if RHS is a boxed variable (could be a struct or other variable)
290
- needsBoxedAccessRHS := false
282
+ // Determine if RHS is a variable referenced variable (could be a struct or other variable)
283
+ needsVarRefedAccessRHS := false
291
284
  var rhsObj types.Object
292
285
 
293
286
  // Check if RHS is an identifier (variable name)
@@ -298,17 +291,17 @@ func (c *GoToTSCompiler) writeAssignmentCore(lhs, rhs []ast.Expr, tok token.Toke
298
291
  rhsObj = c.pkg.TypesInfo.Defs[rhsIdent]
299
292
  }
300
293
 
301
- // Important: For struct copying, we need to check if the variable itself is boxed
302
- // Important: For struct copying, we need to check if the variable needs boxed access
303
- // This is more comprehensive than just checking if it's boxed
294
+ // Important: For struct copying, we need to check if the variable itself is variable referenced
295
+ // Important: For struct copying, we need to check if the variable needs variable referenced access
296
+ // This is more comprehensive than just checking if it's variable referenced
304
297
  if rhsObj != nil {
305
- needsBoxedAccessRHS = c.analysis.NeedsBoxedAccess(rhsObj)
298
+ needsVarRefedAccessRHS = c.analysis.NeedsVarRefAccess(rhsObj)
306
299
  }
307
300
  }
308
301
 
309
302
  // Handle different cases for struct cloning
310
303
  if shouldApplyClone(c.pkg, r) {
311
- // For other expressions, we need to handle boxed access differently
304
+ // For other expressions, we need to handle variable referenced access differently
312
305
  if _, isIdent := r.(*ast.Ident); isIdent {
313
306
  // For identifiers, WriteValueExpr already adds .value if needed
314
307
  if err := c.WriteValueExpr(r); err != nil {
@@ -319,14 +312,15 @@ func (c *GoToTSCompiler) writeAssignmentCore(lhs, rhs []ast.Expr, tok token.Toke
319
312
  if err := c.WriteValueExpr(r); err != nil {
320
313
  return err
321
314
  }
322
- // Only add .value for non-identifiers that need boxed access
323
- if needsBoxedAccessRHS {
324
- c.tsw.WriteLiterally(".value") // Access the boxed value
315
+ // Only add .value for non-identifiers that need variable referenced access
316
+ if needsVarRefedAccessRHS {
317
+ c.tsw.WriteLiterally(".value") // Access the variable referenced value
325
318
  }
326
319
  }
327
320
 
328
321
  c.tsw.WriteLiterally(".clone()") // Always add clone for struct values
329
322
  } else {
323
+ // Non-struct case: write RHS normally
330
324
  if err := c.WriteValueExpr(r); err != nil { // RHS is a non-struct value
331
325
  return err
332
326
  }
@@ -0,0 +1,90 @@
1
+ package compiler
2
+
3
+ import (
4
+ "context"
5
+ "os"
6
+ "path/filepath"
7
+ "testing"
8
+
9
+ "github.com/sirupsen/logrus"
10
+ )
11
+
12
+ func TestEmitBuiltinOption(t *testing.T) {
13
+ // Create a temporary directory for the test output
14
+ tempDir, err := os.MkdirTemp("", "goscript-test-emit-builtin")
15
+ if err != nil {
16
+ t.Fatalf("Failed to create temp dir: %v", err)
17
+ }
18
+ defer os.RemoveAll(tempDir)
19
+
20
+ // Setup logger
21
+ log := logrus.New()
22
+ log.SetLevel(logrus.DebugLevel)
23
+ le := logrus.NewEntry(log)
24
+
25
+ // Case 1: DisableEmitBuiltin = true (default behavior in compliance tests)
26
+ t.Run("DisableEmitBuiltin=true", func(t *testing.T) {
27
+ outputDir := filepath.Join(tempDir, "disabled")
28
+ config := &Config{
29
+ OutputPath: outputDir,
30
+ AllDependencies: true,
31
+ DisableEmitBuiltin: true,
32
+ }
33
+
34
+ compiler, err := NewCompiler(config, le, nil)
35
+ if err != nil {
36
+ t.Fatalf("Failed to create compiler: %v", err)
37
+ }
38
+
39
+ // Compile a package that depends on builtin (time)
40
+ _, err = compiler.CompilePackages(context.Background(), "time")
41
+ if err != nil {
42
+ t.Fatalf("Compilation failed: %v", err)
43
+ }
44
+
45
+ // Check that the unsafe package wasn't emitted (we know it's handwritten)
46
+ unsafePath := filepath.Join(outputDir, "@goscript/unsafe")
47
+ if _, err := os.Stat(unsafePath); !os.IsNotExist(err) {
48
+ t.Errorf("unsafe package was emitted when DisableEmitBuiltin=true")
49
+ }
50
+
51
+ // Also check for runtime package
52
+ runtimePath := filepath.Join(outputDir, "@goscript/runtime")
53
+ if _, err := os.Stat(runtimePath); !os.IsNotExist(err) {
54
+ t.Errorf("runtime package was emitted when DisableEmitBuiltin=true")
55
+ }
56
+
57
+ // But time package should have been emitted
58
+ timePath := filepath.Join(outputDir, "@goscript/time")
59
+ if _, err := os.Stat(timePath); os.IsNotExist(err) {
60
+ t.Errorf("time package was not emitted")
61
+ }
62
+ })
63
+
64
+ // Case 2: DisableEmitBuiltin = false (new behavior for third-party projects)
65
+ t.Run("DisableEmitBuiltin=false", func(t *testing.T) {
66
+ outputDir := filepath.Join(tempDir, "enabled")
67
+ config := &Config{
68
+ OutputPath: outputDir,
69
+ AllDependencies: true,
70
+ DisableEmitBuiltin: false,
71
+ }
72
+
73
+ compiler, err := NewCompiler(config, le, nil)
74
+ if err != nil {
75
+ t.Fatalf("Failed to create compiler: %v", err)
76
+ }
77
+
78
+ // Compile a package that depends on builtin (time)
79
+ _, err = compiler.CompilePackages(context.Background(), "time")
80
+ if err != nil {
81
+ t.Fatalf("Compilation failed: %v", err)
82
+ }
83
+
84
+ // Time package should also have been emitted
85
+ timePath := filepath.Join(outputDir, "@goscript/time")
86
+ if _, err := os.Stat(timePath); os.IsNotExist(err) {
87
+ t.Errorf("time package was not emitted")
88
+ }
89
+ })
90
+ }