goscript 0.0.58 → 0.0.60

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 (44) hide show
  1. package/README.md +40 -33
  2. package/compiler/analysis.go +184 -43
  3. package/compiler/assignment.go +163 -217
  4. package/compiler/compiler.go +35 -31
  5. package/compiler/composite-lit.go +233 -196
  6. package/compiler/constraint.go +88 -0
  7. package/compiler/decl.go +82 -24
  8. package/compiler/expr-call-async.go +20 -34
  9. package/compiler/expr-call-builtins.go +19 -0
  10. package/compiler/expr-call-helpers.go +0 -28
  11. package/compiler/expr-call-make.go +93 -343
  12. package/compiler/expr-call-type-conversion.go +221 -249
  13. package/compiler/expr-call.go +70 -69
  14. package/compiler/expr-selector.go +21 -24
  15. package/compiler/expr.go +3 -60
  16. package/compiler/protobuf.go +180 -36
  17. package/compiler/spec-value.go +132 -24
  18. package/compiler/spec.go +14 -55
  19. package/compiler/stmt-assign.go +338 -356
  20. package/compiler/stmt-range.go +4 -24
  21. package/compiler/stmt.go +92 -203
  22. package/compiler/type-utils.go +185 -0
  23. package/compiler/type.go +26 -80
  24. package/dist/gs/builtin/slice.d.ts +1 -1
  25. package/dist/gs/builtin/slice.js +3 -0
  26. package/dist/gs/builtin/slice.js.map +1 -1
  27. package/dist/gs/builtin/type.js +8 -2
  28. package/dist/gs/builtin/type.js.map +1 -1
  29. package/dist/gs/fmt/fmt.js +113 -16
  30. package/dist/gs/fmt/fmt.js.map +1 -1
  31. package/dist/gs/runtime/runtime.d.ts +1 -1
  32. package/dist/gs/runtime/runtime.js +1 -1
  33. package/dist/gs/slices/slices.d.ts +23 -0
  34. package/dist/gs/slices/slices.js +61 -0
  35. package/dist/gs/slices/slices.js.map +1 -1
  36. package/go.mod +10 -10
  37. package/go.sum +22 -14
  38. package/gs/builtin/slice.ts +5 -2
  39. package/gs/builtin/type.ts +13 -6
  40. package/gs/fmt/fmt.test.ts +176 -0
  41. package/gs/fmt/fmt.ts +109 -18
  42. package/gs/runtime/runtime.ts +1 -1
  43. package/gs/slices/slices.ts +68 -0
  44. package/package.json +3 -3
@@ -6,17 +6,13 @@ import (
6
6
  "strings"
7
7
  )
8
8
 
9
- // writeAsyncCallIfNeeded writes the await prefix for async function or method calls
10
- // Returns true if await was written, false otherwise
11
- func (c *GoToTSCompiler) writeAsyncCallIfNeeded(exp *ast.CallExpr) bool {
9
+ // isCallExprAsync determines if a CallExpr represents an async function/method call
10
+ func (c *GoToTSCompiler) isCallExprAsync(exp *ast.CallExpr) bool {
12
11
  switch fun := exp.Fun.(type) {
13
12
  case *ast.Ident:
14
13
  // Function call (e.g., func())
15
- if obj := c.pkg.TypesInfo.Uses[fun]; obj != nil {
16
- if c.analysis.IsAsyncFunc(obj) {
17
- c.tsw.WriteLiterally("await ")
18
- return true
19
- }
14
+ if obj := c.objectOfIdent(fun); obj != nil {
15
+ return c.analysis.IsAsyncFunc(obj)
20
16
  }
21
17
  return false
22
18
 
@@ -29,13 +25,13 @@ func (c *GoToTSCompiler) writeAsyncCallIfNeeded(exp *ast.CallExpr) bool {
29
25
  switch x := fun.X.(type) {
30
26
  case *ast.Ident:
31
27
  // Direct identifier: obj.method()
32
- obj = c.pkg.TypesInfo.Uses[x]
28
+ obj = c.objectOfIdent(x)
33
29
  objOk = obj != nil
34
30
 
35
31
  case *ast.StarExpr:
36
32
  // Pointer dereference: (*p).method() or p.method() where p is a pointer
37
33
  if id, isIdent := x.X.(*ast.Ident); isIdent {
38
- obj = c.pkg.TypesInfo.Uses[id]
34
+ obj = c.objectOfIdent(id)
39
35
  objOk = obj != nil
40
36
  }
41
37
 
@@ -43,8 +39,6 @@ func (c *GoToTSCompiler) writeAsyncCallIfNeeded(exp *ast.CallExpr) bool {
43
39
  // Field access: obj.field.method()
44
40
  // Get the type of the field access expression
45
41
  if fieldType := c.pkg.TypesInfo.TypeOf(x); fieldType != nil {
46
- // For field access, we create a synthetic object representing the field type
47
- // We'll handle this case below when we determine the method's type
48
42
  objOk = true
49
43
  }
50
44
 
@@ -61,13 +55,7 @@ func (c *GoToTSCompiler) writeAsyncCallIfNeeded(exp *ast.CallExpr) bool {
61
55
  if pkgName, isPkg := obj.(*types.PkgName); isPkg {
62
56
  methodName := fun.Sel.Name
63
57
  pkgPath := pkgName.Imported().Path()
64
-
65
- // Check if this package-level function is async (empty TypeName)
66
- if c.analysis.IsMethodAsync(pkgPath, "", methodName) {
67
- c.tsw.WriteLiterally("await ")
68
- return true
69
- }
70
- return false
58
+ return c.analysis.IsMethodAsync(pkgPath, "", methodName)
71
59
  }
72
60
  }
73
61
 
@@ -83,7 +71,6 @@ func (c *GoToTSCompiler) writeAsyncCallIfNeeded(exp *ast.CallExpr) bool {
83
71
  }
84
72
  } else {
85
73
  // Field access case: obj.field.method()
86
- // Get the type of the field access expression
87
74
  targetType = c.pkg.TypesInfo.TypeOf(fun.X)
88
75
  if targetType == nil {
89
76
  return false
@@ -94,12 +81,7 @@ func (c *GoToTSCompiler) writeAsyncCallIfNeeded(exp *ast.CallExpr) bool {
94
81
 
95
82
  // Check if target type is an interface
96
83
  if interfaceType, isInterface := targetType.Underlying().(*types.Interface); isInterface {
97
- // Interface method call: use interface method async analysis
98
- if c.analysis.IsInterfaceMethodAsync(interfaceType, methodName) {
99
- c.tsw.WriteLiterally("await ")
100
- return true
101
- }
102
- return false
84
+ return c.analysis.IsInterfaceMethodAsync(interfaceType, methodName)
103
85
  }
104
86
 
105
87
  // Get the named type from the target type
@@ -128,22 +110,26 @@ func (c *GoToTSCompiler) writeAsyncCallIfNeeded(exp *ast.CallExpr) bool {
128
110
  if typePkg != nil {
129
111
  pkgPath = typePkg.Path()
130
112
  } else {
131
- // Fallback to current package
132
113
  pkgPath = c.pkg.Types.Path()
133
114
  }
134
115
 
135
- // Check if this method is async using unified analysis
136
- if c.analysis.IsMethodAsync(pkgPath, typeName, methodName) {
137
- c.tsw.WriteLiterally("await ")
138
- return true
139
- }
140
- return false
116
+ return c.analysis.IsMethodAsync(pkgPath, typeName, methodName)
141
117
 
142
118
  default:
143
119
  return false
144
120
  }
145
121
  }
146
122
 
123
+ // writeAsyncCallIfNeeded writes the await prefix for async function or method calls
124
+ // Returns true if await was written, false otherwise
125
+ func (c *GoToTSCompiler) writeAsyncCallIfNeeded(exp *ast.CallExpr) bool {
126
+ if c.isCallExprAsync(exp) {
127
+ c.tsw.WriteLiterally("await ")
128
+ return true
129
+ }
130
+ return false
131
+ }
132
+
147
133
  // addNonNullAssertion adds ! for function calls that might return null
148
134
  func (c *GoToTSCompiler) addNonNullAssertion(expFun ast.Expr) {
149
135
  if funType := c.pkg.TypesInfo.TypeOf(expFun); funType != nil {
@@ -151,7 +137,7 @@ func (c *GoToTSCompiler) addNonNullAssertion(expFun ast.Expr) {
151
137
  // Check if this is a function parameter identifier that needs not-null assertion
152
138
  if ident, isIdent := expFun.(*ast.Ident); isIdent {
153
139
  // Check if this identifier is a function parameter
154
- if obj := c.pkg.TypesInfo.Uses[ident]; obj != nil {
140
+ if obj := c.objectOfIdent(ident); obj != nil {
155
141
  if _, isVar := obj.(*types.Var); isVar {
156
142
  // This is a variable (including function parameters)
157
143
  // Function parameters that are function types need ! assertion
@@ -8,6 +8,25 @@ import (
8
8
  "github.com/pkg/errors"
9
9
  )
10
10
 
11
+ // builtinFunctions is the definitive list of Go builtin functions handled by the compiler
12
+ var builtinFunctions = map[string]bool{
13
+ "len": true,
14
+ "cap": true,
15
+ "make": true,
16
+ "new": true,
17
+ "append": true,
18
+ "copy": true,
19
+ "delete": true,
20
+ "complex": true,
21
+ "real": true,
22
+ "imag": true,
23
+ "close": true,
24
+ "panic": true,
25
+ "recover": true,
26
+ "print": true,
27
+ "println": true,
28
+ }
29
+
11
30
  // writeBuiltinFunction handles built-in Go functions
12
31
  func (c *GoToTSCompiler) writeBuiltinFunction(exp *ast.CallExpr, funName string) (handled bool, err error) {
13
32
  switch funName {
@@ -7,34 +7,6 @@ import (
7
7
  "github.com/pkg/errors"
8
8
  )
9
9
 
10
- // isByteSliceType checks if a type is []byte (slice of uint8)
11
- func (c *GoToTSCompiler) isByteSliceType(t types.Type) bool {
12
- if sliceType, isSlice := t.Underlying().(*types.Slice); isSlice {
13
- if basicElem, isBasic := sliceType.Elem().(*types.Basic); isBasic && basicElem.Kind() == types.Uint8 {
14
- return true
15
- }
16
- }
17
- return false
18
- }
19
-
20
- // isRuneSliceType checks if a type is []rune (slice of int32)
21
- func (c *GoToTSCompiler) isRuneSliceType(t types.Type) bool {
22
- if sliceType, isSlice := t.Underlying().(*types.Slice); isSlice {
23
- if basicElem, isBasic := sliceType.Elem().(*types.Basic); isBasic && basicElem.Kind() == types.Int32 {
24
- return true
25
- }
26
- }
27
- return false
28
- }
29
-
30
- // isStringType checks if a type is string
31
- func (c *GoToTSCompiler) isStringType(t types.Type) bool {
32
- if basic, isBasic := t.Underlying().(*types.Basic); isBasic {
33
- return basic.Kind() == types.String || basic.Kind() == types.UntypedString
34
- }
35
- return false
36
- }
37
-
38
10
  // writeByteSliceCreation handles the creation of []byte slices with proper Uint8Array handling
39
11
  func (c *GoToTSCompiler) writeByteSliceCreation(lengthArg, capacityArg interface{}) error {
40
12
  return c.writeSliceCreationForType(lengthArg, capacityArg, true)