goscript 0.0.37 → 0.0.39

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 (198) hide show
  1. package/compiler/analysis.go +129 -8
  2. package/compiler/compiler.go +4 -1
  3. package/compiler/composite-lit.go +2 -4
  4. package/compiler/expr-call.go +12 -0
  5. package/compiler/lit.go +100 -6
  6. package/compiler/protobuf.go +2 -2
  7. package/compiler/spec-value.go +3 -3
  8. package/compiler/spec.go +6 -3
  9. package/compiler/stmt-assign.go +1 -1
  10. package/dist/gs/builtin/builtin.d.ts +45 -0
  11. package/dist/gs/builtin/builtin.js +197 -0
  12. package/dist/gs/builtin/builtin.js.map +1 -1
  13. package/dist/gs/builtin/slice.js +2 -1
  14. package/dist/gs/builtin/slice.js.map +1 -1
  15. package/dist/gs/bytes/buffer.gs.d.ts +56 -0
  16. package/dist/gs/bytes/buffer.gs.js +611 -0
  17. package/dist/gs/bytes/buffer.gs.js.map +1 -0
  18. package/dist/gs/bytes/bytes.gs.d.ts +78 -0
  19. package/dist/gs/bytes/bytes.gs.js +1011 -0
  20. package/dist/gs/bytes/bytes.gs.js.map +1 -0
  21. package/dist/gs/bytes/index.d.ts +4 -0
  22. package/dist/gs/bytes/index.js +5 -0
  23. package/dist/gs/bytes/index.js.map +1 -0
  24. package/dist/gs/bytes/iter.gs.d.ts +9 -0
  25. package/dist/gs/bytes/iter.gs.js +143 -0
  26. package/dist/gs/bytes/iter.gs.js.map +1 -0
  27. package/dist/gs/bytes/reader.gs.d.ts +34 -0
  28. package/dist/gs/bytes/reader.gs.js +198 -0
  29. package/dist/gs/bytes/reader.gs.js.map +1 -0
  30. package/dist/gs/github.com/pkg/errors/errors.d.ts +1 -1
  31. package/dist/gs/github.com/pkg/errors/errors.js +182 -23
  32. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  33. package/dist/gs/github.com/pkg/errors/go113.d.ts +1 -1
  34. package/dist/gs/github.com/pkg/errors/go113.js +1 -1
  35. package/dist/gs/github.com/pkg/errors/go113.js.map +1 -1
  36. package/dist/gs/github.com/pkg/errors/index.d.ts +3 -3
  37. package/dist/gs/github.com/pkg/errors/index.js +3 -3
  38. package/dist/gs/github.com/pkg/errors/index.js.map +1 -1
  39. package/dist/gs/github.com/pkg/errors/stack.d.ts +1 -1
  40. package/dist/gs/github.com/pkg/errors/stack.js +8 -5
  41. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
  42. package/dist/gs/internal/abi/index.d.ts +20 -0
  43. package/dist/gs/internal/abi/index.js +20 -0
  44. package/dist/gs/internal/abi/index.js.map +1 -0
  45. package/dist/gs/internal/bytealg/index.d.ts +14 -0
  46. package/dist/gs/internal/bytealg/index.js +139 -0
  47. package/dist/gs/internal/bytealg/index.js.map +1 -0
  48. package/dist/gs/internal/byteorder/index.d.ts +1 -1
  49. package/dist/gs/internal/byteorder/index.js +4 -4
  50. package/dist/gs/internal/byteorder/index.js.map +1 -1
  51. package/dist/gs/math/index.d.ts +44 -44
  52. package/dist/gs/math/index.js +44 -44
  53. package/dist/gs/math/index.js.map +1 -1
  54. package/dist/gs/os/index.d.ts +19 -19
  55. package/dist/gs/os/index.js +19 -19
  56. package/dist/gs/os/index.js.map +1 -1
  57. package/dist/gs/reflect/deepequal.d.ts +2 -0
  58. package/dist/gs/reflect/deepequal.js +91 -0
  59. package/dist/gs/reflect/deepequal.js.map +1 -0
  60. package/dist/gs/reflect/index.d.ts +8 -0
  61. package/dist/gs/reflect/index.js +10 -0
  62. package/dist/gs/reflect/index.js.map +1 -0
  63. package/dist/gs/reflect/iter.d.ts +4 -0
  64. package/dist/gs/reflect/iter.js +24 -0
  65. package/dist/gs/reflect/iter.js.map +1 -0
  66. package/dist/gs/reflect/map.d.ts +20 -0
  67. package/dist/gs/reflect/map.js +74 -0
  68. package/dist/gs/reflect/map.js.map +1 -0
  69. package/dist/gs/reflect/swapper.d.ts +2 -0
  70. package/dist/gs/reflect/swapper.js +46 -0
  71. package/dist/gs/reflect/swapper.js.map +1 -0
  72. package/dist/gs/reflect/type.d.ts +134 -0
  73. package/dist/gs/reflect/type.js +825 -0
  74. package/dist/gs/reflect/type.js.map +1 -0
  75. package/dist/gs/reflect/types.d.ts +90 -0
  76. package/dist/gs/reflect/types.js +119 -0
  77. package/dist/gs/reflect/types.js.map +1 -0
  78. package/dist/gs/reflect/value.d.ts +13 -0
  79. package/dist/gs/reflect/value.js +202 -0
  80. package/dist/gs/reflect/value.js.map +1 -0
  81. package/dist/gs/reflect/visiblefields.d.ts +4 -0
  82. package/dist/gs/reflect/visiblefields.js +149 -0
  83. package/dist/gs/reflect/visiblefields.js.map +1 -0
  84. package/dist/gs/strconv/index.d.ts +6 -6
  85. package/dist/gs/strconv/index.js +6 -6
  86. package/dist/gs/strconv/index.js.map +1 -1
  87. package/dist/gs/strings/index.d.ts +1 -1
  88. package/dist/gs/strings/index.js +1 -1
  89. package/dist/gs/strings/index.js.map +1 -1
  90. package/dist/gs/strings/replace.js.map +1 -1
  91. package/dist/gs/sync/atomic/index.d.ts +4 -4
  92. package/dist/gs/sync/atomic/index.js +4 -4
  93. package/dist/gs/sync/atomic/index.js.map +1 -1
  94. package/dist/gs/syscall/index.d.ts +6 -6
  95. package/dist/gs/syscall/index.js +34 -28
  96. package/dist/gs/syscall/index.js.map +1 -1
  97. package/dist/gs/unicode/utf8/utf8.d.ts +1 -1
  98. package/dist/gs/unicode/utf8/utf8.js +4 -2
  99. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  100. package/dist/gs/unsafe/unsafe.js.map +1 -1
  101. package/gs/builtin/builtin.ts +219 -0
  102. package/gs/builtin/slice.ts +2 -1
  103. package/gs/bytes/buffer.gs.ts +614 -0
  104. package/gs/bytes/bytes.gs.ts +1180 -0
  105. package/gs/bytes/godoc.txt +69 -0
  106. package/gs/bytes/index.ts +69 -0
  107. package/gs/bytes/iter.gs.ts +149 -0
  108. package/gs/bytes/reader.gs.ts +230 -0
  109. package/gs/github.com/pkg/errors/errors.ts +408 -238
  110. package/gs/github.com/pkg/errors/go113.ts +5 -6
  111. package/gs/github.com/pkg/errors/index.ts +12 -3
  112. package/gs/github.com/pkg/errors/stack.ts +107 -105
  113. package/gs/internal/abi/index.ts +37 -0
  114. package/gs/internal/bytealg/index.ts +149 -0
  115. package/gs/internal/byteorder/index.ts +5 -5
  116. package/gs/math/abs.gs.test.ts +1 -1
  117. package/gs/math/acosh.gs.test.ts +4 -2
  118. package/gs/math/asin.gs.test.ts +1 -1
  119. package/gs/math/asinh.gs.test.ts +7 -3
  120. package/gs/math/atan.gs.test.ts +1 -1
  121. package/gs/math/atan2.gs.test.ts +17 -9
  122. package/gs/math/atanh.gs.test.ts +1 -1
  123. package/gs/math/bits.gs.test.ts +1 -1
  124. package/gs/math/cbrt.gs.test.ts +1 -1
  125. package/gs/math/const.gs.test.ts +34 -8
  126. package/gs/math/copysign.gs.test.ts +7 -3
  127. package/gs/math/dim.gs.test.ts +19 -7
  128. package/gs/math/erf.gs.test.ts +1 -1
  129. package/gs/math/erfinv.gs.test.ts +4 -2
  130. package/gs/math/exp.gs.test.ts +1 -1
  131. package/gs/math/expm1.gs.test.ts +6 -4
  132. package/gs/math/floor.gs.test.ts +17 -4
  133. package/gs/math/fma.gs.test.ts +53 -53
  134. package/gs/math/frexp.gs.test.ts +112 -117
  135. package/gs/math/gamma.gs.test.ts +1 -1
  136. package/gs/math/hypot.gs.test.ts +53 -53
  137. package/gs/math/index.ts +80 -44
  138. package/gs/math/j0.gs.test.ts +6 -2
  139. package/gs/math/j1.gs.test.ts +6 -2
  140. package/gs/math/jn.gs.test.ts +9 -5
  141. package/gs/math/ldexp.gs.test.ts +103 -86
  142. package/gs/math/lgamma.gs.test.ts +10 -10
  143. package/gs/math/log.gs.test.ts +1 -1
  144. package/gs/math/log10.gs.test.ts +1 -1
  145. package/gs/math/log1p.gs.test.ts +2 -2
  146. package/gs/math/logb.gs.test.ts +1 -1
  147. package/gs/math/mod.gs.test.ts +2 -2
  148. package/gs/math/modf.gs.test.ts +7 -7
  149. package/gs/math/nextafter.gs.test.ts +9 -7
  150. package/gs/math/pow.gs.test.ts +6 -4
  151. package/gs/math/pow10.gs.test.ts +1 -1
  152. package/gs/math/remainder.gs.test.ts +1 -1
  153. package/gs/math/signbit.gs.test.ts +1 -1
  154. package/gs/math/sin.gs.test.ts +1 -1
  155. package/gs/math/sincos.gs.test.ts +33 -14
  156. package/gs/math/sinh.gs.test.ts +1 -1
  157. package/gs/math/sqrt.gs.test.ts +1 -1
  158. package/gs/math/tan.gs.test.ts +3 -3
  159. package/gs/math/tanh.gs.test.ts +1 -1
  160. package/gs/os/index.ts +128 -19
  161. package/gs/reflect/ANALYSIS.md +278 -0
  162. package/gs/reflect/deepequal.test.ts +41 -0
  163. package/gs/reflect/deepequal.ts +169 -0
  164. package/gs/reflect/function-types.test.ts +146 -0
  165. package/gs/reflect/godoc.txt +67 -0
  166. package/gs/reflect/index.ts +83 -0
  167. package/gs/reflect/iter.ts +44 -0
  168. package/gs/reflect/map.test.ts +30 -0
  169. package/gs/reflect/map.ts +85 -0
  170. package/gs/reflect/swapper.ts +52 -0
  171. package/gs/reflect/type.ts +1016 -0
  172. package/gs/reflect/types.ts +214 -0
  173. package/gs/reflect/value.ts +270 -0
  174. package/gs/reflect/visiblefields.ts +177 -0
  175. package/gs/strconv/index.ts +39 -6
  176. package/gs/strings/index.ts +7 -1
  177. package/gs/strings/replace.ts +1 -9
  178. package/gs/sync/atomic/index.ts +53 -4
  179. package/gs/syscall/index.ts +45 -37
  180. package/gs/unicode/utf8/utf8.ts +8 -5
  181. package/gs/unsafe/unsafe.ts +1 -1
  182. package/package.json +2 -1
  183. package/dist/gs/internal/testlog/index.d.ts +0 -1
  184. package/dist/gs/internal/testlog/index.js +0 -5
  185. package/dist/gs/internal/testlog/index.js.map +0 -1
  186. package/dist/gs/maps/iter.gs.d.ts +0 -7
  187. package/dist/gs/maps/iter.gs.js +0 -65
  188. package/dist/gs/maps/iter.gs.js.map +0 -1
  189. package/dist/gs/maps/maps.gs.d.ts +0 -7
  190. package/dist/gs/maps/maps.gs.js +0 -79
  191. package/dist/gs/maps/maps.gs.js.map +0 -1
  192. package/dist/gs/stringslite/index.d.ts +0 -1
  193. package/dist/gs/stringslite/index.js +0 -2
  194. package/dist/gs/stringslite/index.js.map +0 -1
  195. package/dist/gs/stringslite/strings.d.ts +0 -11
  196. package/dist/gs/stringslite/strings.js +0 -67
  197. package/dist/gs/stringslite/strings.js.map +0 -1
  198. package/gs/internal/testlog/index.ts +0 -7
@@ -43,12 +43,25 @@ type VariableUsageInfo struct {
43
43
  Destinations []AssignmentInfo
44
44
  }
45
45
 
46
+ // FunctionTypeInfo represents Go function type information for reflection
47
+ type FunctionTypeInfo struct {
48
+ Params []types.Type // Parameter types
49
+ Results []types.Type // Return types
50
+ Variadic bool // Whether the function is variadic
51
+ }
52
+
46
53
  // FunctionInfo consolidates function-related tracking data.
47
54
  type FunctionInfo struct {
48
55
  IsAsync bool
49
56
  NamedReturns []string
50
57
  }
51
58
 
59
+ // ReflectedFunctionInfo tracks functions that need reflection support
60
+ type ReflectedFunctionInfo struct {
61
+ FuncType *types.Signature // The function's type signature
62
+ NeedsReflect bool // Whether this function is used with reflection
63
+ }
64
+
52
65
  // NodeInfo consolidates node-related tracking data.
53
66
  type NodeInfo struct {
54
67
  NeedsDefer bool
@@ -84,6 +97,12 @@ type Analysis struct {
84
97
  // FuncLitData tracks function literal specific data since they don't have types.Object
85
98
  FuncLitData map[*ast.FuncLit]*FunctionInfo
86
99
 
100
+ // ReflectedFunctions tracks functions that need reflection type metadata
101
+ ReflectedFunctions map[ast.Node]*ReflectedFunctionInfo
102
+
103
+ // FunctionAssignments tracks which function literals are assigned to which variables
104
+ FunctionAssignments map[types.Object]ast.Node
105
+
87
106
  // PackageMetadata holds package-level metadata
88
107
  PackageMetadata map[string]interface{}
89
108
  }
@@ -102,12 +121,14 @@ type PackageAnalysis struct {
102
121
  // NewAnalysis creates a new Analysis instance.
103
122
  func NewAnalysis() *Analysis {
104
123
  return &Analysis{
105
- VariableUsage: make(map[types.Object]*VariableUsageInfo),
106
- Imports: make(map[string]*fileImport),
107
- FunctionData: make(map[types.Object]*FunctionInfo),
108
- NodeData: make(map[ast.Node]*NodeInfo),
109
- FuncLitData: make(map[*ast.FuncLit]*FunctionInfo),
110
- PackageMetadata: make(map[string]interface{}),
124
+ VariableUsage: make(map[types.Object]*VariableUsageInfo),
125
+ Imports: make(map[string]*fileImport),
126
+ FunctionData: make(map[types.Object]*FunctionInfo),
127
+ NodeData: make(map[ast.Node]*NodeInfo),
128
+ FuncLitData: make(map[*ast.FuncLit]*FunctionInfo),
129
+ ReflectedFunctions: make(map[ast.Node]*ReflectedFunctionInfo),
130
+ FunctionAssignments: make(map[types.Object]ast.Node),
131
+ PackageMetadata: make(map[string]interface{}),
111
132
  }
112
133
  }
113
134
 
@@ -341,6 +362,10 @@ func (v *analysisVisitor) Visit(node ast.Node) ast.Visitor {
341
362
  // Case: var lhs = rhs_ident
342
363
  assignmentType = DirectAssignment
343
364
  sourceObj = v.pkg.TypesInfo.ObjectOf(rhsIdent)
365
+ } else if funcLit, ok := rhsExpr.(*ast.FuncLit); ok {
366
+ // Case: var lhs = func(...) { ... }
367
+ // Track function literal assignment
368
+ v.analysis.FunctionAssignments[lhsObj] = funcLit
344
369
  }
345
370
 
346
371
  // --- Record Usage ---
@@ -578,6 +603,9 @@ func (v *analysisVisitor) Visit(node ast.Node) ast.Visitor {
578
603
  }
579
604
  }
580
605
 
606
+ // Check for reflect function calls that operate on functions
607
+ v.checkReflectUsage(n)
608
+
581
609
  // Store async state for this call expression
582
610
  if v.analysis.NodeData[n] == nil {
583
611
  v.analysis.NodeData[n] = &NodeInfo{}
@@ -637,16 +665,21 @@ func (v *analysisVisitor) Visit(node ast.Node) ast.Visitor {
637
665
  continue // Skip blank identifier assignments
638
666
  }
639
667
  lhsTrackedObj = v.pkg.TypesInfo.ObjectOf(lhsIdent)
668
+
669
+ // Check if RHS is a function literal and track the assignment
670
+ if funcLit, ok := currentRHSExpr.(*ast.FuncLit); ok {
671
+ v.analysis.FunctionAssignments[lhsTrackedObj] = funcLit
672
+ }
640
673
  } else if selExpr, ok := currentLHSExpr.(*ast.SelectorExpr); ok {
641
674
  // LHS is struct.field or package.Var
642
675
  if selection := v.pkg.TypesInfo.Selections[selExpr]; selection != nil {
643
676
  lhsTrackedObj = selection.Obj() // This is the field or selected var object
644
677
  }
645
- } else if _, ok := currentLHSExpr.(*ast.StarExpr); ok {
678
+ } /* else if _, ok := currentLHSExpr.(*ast.StarExpr); ok {
646
679
  // LHS is *pointer.
647
680
  // We don't try to get a types.Object for the dereferenced entity itself to store in VariableUsage.
648
681
  // lhsTrackedObj remains nil. The effect on rhsSourceObj (if its address is taken) is handled below.
649
- }
682
+ } */
650
683
  // For other complex LHS (e.g., map_expr[key_expr]), lhsTrackedObj remains nil.
651
684
 
652
685
  // --- Record Usage Information ---
@@ -1095,3 +1128,91 @@ func (a *Analysis) IsMethodAsync(pkgName, typeName, methodName string) bool {
1095
1128
 
1096
1129
  return false
1097
1130
  }
1131
+
1132
+ // NeedsReflectionMetadata returns whether the given function node needs reflection type metadata
1133
+ func (a *Analysis) NeedsReflectionMetadata(node ast.Node) bool {
1134
+ if node == nil {
1135
+ return false
1136
+ }
1137
+ reflectInfo := a.ReflectedFunctions[node]
1138
+ return reflectInfo != nil && reflectInfo.NeedsReflect
1139
+ }
1140
+
1141
+ // GetFunctionTypeInfo returns the function type information for reflection
1142
+ func (a *Analysis) GetFunctionTypeInfo(node ast.Node) *ReflectedFunctionInfo {
1143
+ if node == nil {
1144
+ return nil
1145
+ }
1146
+ return a.ReflectedFunctions[node]
1147
+ }
1148
+
1149
+ // MarkFunctionForReflection marks a function node as needing reflection support
1150
+ func (a *Analysis) MarkFunctionForReflection(node ast.Node, funcType *types.Signature) {
1151
+ if node == nil || funcType == nil {
1152
+ return
1153
+ }
1154
+ a.ReflectedFunctions[node] = &ReflectedFunctionInfo{
1155
+ FuncType: funcType,
1156
+ NeedsReflect: true,
1157
+ }
1158
+ }
1159
+
1160
+ // checkReflectUsage checks for reflect function calls that operate on functions
1161
+ func (v *analysisVisitor) checkReflectUsage(callExpr *ast.CallExpr) {
1162
+ // Check if this is a reflect package function call
1163
+ if selExpr, ok := callExpr.Fun.(*ast.SelectorExpr); ok {
1164
+ // Check if the selector is from reflect package
1165
+ if ident, ok := selExpr.X.(*ast.Ident); ok {
1166
+ // Check if this is a reflect package call (reflect.TypeOf, reflect.ValueOf, etc.)
1167
+ if obj := v.pkg.TypesInfo.Uses[ident]; obj != nil {
1168
+ if pkgName, ok := obj.(*types.PkgName); ok && pkgName.Imported().Path() == "reflect" {
1169
+ methodName := selExpr.Sel.Name
1170
+
1171
+ // Check for reflect.TypeOf and reflect.ValueOf calls
1172
+ if methodName == "TypeOf" || methodName == "ValueOf" {
1173
+ // Check if any argument is a function
1174
+ for _, arg := range callExpr.Args {
1175
+ v.checkReflectArgument(arg)
1176
+ }
1177
+ }
1178
+ }
1179
+ }
1180
+ }
1181
+ }
1182
+ }
1183
+
1184
+ // checkReflectArgument checks if an argument to a reflect function is a function that needs metadata
1185
+ func (v *analysisVisitor) checkReflectArgument(arg ast.Expr) {
1186
+ // Check if the argument is an identifier (variable)
1187
+ if ident, ok := arg.(*ast.Ident); ok {
1188
+ // Get the object this identifier refers to
1189
+ if obj := v.pkg.TypesInfo.Uses[ident]; obj != nil {
1190
+ // Check if this object has a function type
1191
+ if funcType, ok := obj.Type().(*types.Signature); ok {
1192
+ // This is a function variable being passed to reflect
1193
+ // We need to find the original function definition/assignment
1194
+ v.markFunctionVariable(ident, funcType)
1195
+ }
1196
+ }
1197
+ } else if funcLit, ok := arg.(*ast.FuncLit); ok {
1198
+ // This is a function literal being passed directly to reflect
1199
+ if funcType := v.pkg.TypesInfo.Types[funcLit].Type.(*types.Signature); funcType != nil {
1200
+ v.analysis.MarkFunctionForReflection(funcLit, funcType)
1201
+ }
1202
+ }
1203
+ }
1204
+
1205
+ // markFunctionVariable finds the function definition/assignment for a variable and marks it for reflection
1206
+ func (v *analysisVisitor) markFunctionVariable(ident *ast.Ident, funcType *types.Signature) {
1207
+ // Get the object for this identifier
1208
+ obj := v.pkg.TypesInfo.Uses[ident]
1209
+ if obj == nil {
1210
+ return
1211
+ }
1212
+
1213
+ // Check if we have a tracked function assignment for this variable
1214
+ if funcNode := v.analysis.FunctionAssignments[obj]; funcNode != nil {
1215
+ // Mark the function node for reflection
1216
+ v.analysis.MarkFunctionForReflection(funcNode, funcType)
1217
+ }
1218
+ }
@@ -453,7 +453,10 @@ func (c *PackageCompiler) generateIndexFile(compiledFiles []string) error {
453
453
  if strings.HasSuffix(fileName, ".pb") {
454
454
  // For protobuf files, add a simple re-export
455
455
  pbTsFileName := fileName + ".ts"
456
- if err := c.writeProtobufExports(indexFile, fileName, pbTsFileName); err != nil {
456
+ if err := func() error {
457
+ var _ string = pbTsFileName
458
+ return c.writeProtobufExports(indexFile, fileName)
459
+ }(); err != nil {
457
460
  return err
458
461
  }
459
462
  continue
@@ -503,14 +503,12 @@ func (c *GoToTSCompiler) WriteCompositeLit(exp *ast.CompositeLit) error {
503
503
  case *types.Pointer:
504
504
  // Handle pointer to composite literal
505
505
  ptrType := underlying.(*types.Pointer)
506
- elemType := ptrType.Elem().Underlying()
507
- switch elemType.(type) {
506
+ switch elemType := ptrType.Elem().Underlying().(type) {
508
507
  case *types.Struct:
509
508
  // This is an anonymous struct literal with inferred pointer type
510
509
  // Just create the struct object directly - no var-refing needed
511
510
  // Anonymous literals are not variables, so they don't get var-refed
512
- structType := elemType.(*types.Struct)
513
- return c.writeUntypedStructLiteral(exp, structType) // true = anonymous
511
+ return c.writeUntypedStructLiteral(exp, elemType) // true = anonymous
514
512
  default:
515
513
  return fmt.Errorf("unhandled pointer composite literal element type: %T", elemType)
516
514
  }
@@ -132,6 +132,18 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
132
132
  return errors.Errorf("unhandled delete call with incorrect number of arguments: %d != 2", len(exp.Args))
133
133
  }
134
134
  c.tsw.WriteLiterally("$.deleteMapEntry")
135
+ case "copy":
136
+ // Translate copy(dst, src) to $.copy(dst, src)
137
+ if len(exp.Args) != 2 {
138
+ return errors.Errorf("unhandled copy call with incorrect number of arguments: %d != 2", len(exp.Args))
139
+ }
140
+ c.tsw.WriteLiterally("$.copy")
141
+ case "recover":
142
+ // Translate recover() to $.recover()
143
+ if len(exp.Args) != 0 {
144
+ return errors.Errorf("unhandled recover call with incorrect number of arguments: %d != 0", len(exp.Args))
145
+ }
146
+ c.tsw.WriteLiterally("$.recover")
135
147
  case "make":
136
148
  // First check if we have a channel type
137
149
  if typ := c.pkg.TypesInfo.TypeOf(exp.Args[0]); typ != nil {
package/compiler/lit.go CHANGED
@@ -70,14 +70,25 @@ func (c *GoToTSCompiler) WriteBasicLit(exp *ast.BasicLit) {
70
70
 
71
71
  // Check if this is a raw string literal (starts and ends with backticks)
72
72
  if len(value) >= 2 && value[0] == '`' && value[len(value)-1] == '`' {
73
- // This is a Go raw string - need to escape invalid \x sequences for JavaScript
73
+ // This is a Go raw string
74
74
  content := value[1 : len(value)-1] // Remove surrounding backticks
75
75
 
76
- // Escape invalid \x, \u, and \U sequences that would cause TS1125 errors
77
- content = c.escapeInvalidEscapeSequences(content)
78
-
79
- // Write as template literal with corrected content
80
- c.tsw.WriteLiterallyf("`%s`", content)
76
+ // Check if the raw string contains backslashes that would be problematic in template literals
77
+ if strings.Contains(content, `\`) {
78
+ // Convert to a regular string literal with proper escaping
79
+ // Replace backslashes with double backslashes for TypeScript
80
+ content = strings.ReplaceAll(content, `\`, `\\`)
81
+ // Replace double quotes with escaped double quotes
82
+ content = strings.ReplaceAll(content, `"`, `\"`)
83
+ // Write as a regular string literal
84
+ c.tsw.WriteLiterallyf(`"%s"`, content)
85
+ } else {
86
+ // No backslashes, safe to use template literal
87
+ // Escape invalid \x, \u, and \U sequences that would cause TS1125 errors
88
+ content = c.escapeInvalidEscapeSequences(content)
89
+ // Write as template literal with corrected content
90
+ c.tsw.WriteLiterallyf("`%s`", content)
91
+ }
81
92
  } else {
82
93
  // Regular string literal (double quotes) - write as-is
83
94
  c.tsw.WriteLiterally(value)
@@ -101,6 +112,17 @@ func (c *GoToTSCompiler) WriteBasicLit(exp *ast.BasicLit) {
101
112
  // - Wrapped in `Promise<>` if `async`.
102
113
  // - The function body (`exp.Body`) is translated using `WriteStmt`.
103
114
  func (c *GoToTSCompiler) WriteFuncLitValue(exp *ast.FuncLit) error {
115
+ // Check if this function needs reflection metadata
116
+ needsReflection := c.analysis.NeedsReflectionMetadata(exp)
117
+
118
+ if needsReflection {
119
+ // Start IIFE to attach metadata
120
+ c.tsw.WriteLiterally("(() => {")
121
+ c.tsw.Indent(1)
122
+ c.tsw.WriteLine("")
123
+ c.tsw.WriteLiterally("const fn = ")
124
+ }
125
+
104
126
  // Determine if the function literal should be async
105
127
  isAsync := c.analysis.IsFuncLitAsync(exp)
106
128
 
@@ -183,6 +205,78 @@ func (c *GoToTSCompiler) WriteFuncLitValue(exp *ast.FuncLit) error {
183
205
  c.tsw.WriteLiterally("}")
184
206
  }
185
207
 
208
+ // Add reflection metadata if needed
209
+ if needsReflection {
210
+ c.tsw.WriteLine("")
211
+
212
+ // Attach type metadata to the function
213
+ if err := c.writeReflectionMetadata(exp); err != nil {
214
+ return fmt.Errorf("failed to write reflection metadata: %w", err)
215
+ }
216
+
217
+ c.tsw.WriteLine("return fn")
218
+ c.tsw.Indent(-1)
219
+ c.tsw.WriteLiterally("})()")
220
+ }
221
+
222
+ return nil
223
+ }
224
+
225
+ // writeReflectionMetadata attaches function type information to a function for reflection support
226
+ func (c *GoToTSCompiler) writeReflectionMetadata(exp *ast.FuncLit) error {
227
+ // Get the reflection info for this function
228
+ reflectInfo := c.analysis.GetFunctionTypeInfo(exp)
229
+ if reflectInfo == nil || reflectInfo.FuncType == nil {
230
+ return nil // No reflection info available
231
+ }
232
+
233
+ funcType := reflectInfo.FuncType
234
+
235
+ // Build FunctionTypeInfo metadata
236
+ c.tsw.WriteLiterally("fn.__typeInfo = {")
237
+ c.tsw.Indent(1)
238
+ c.tsw.WriteLine("")
239
+ c.tsw.WriteLiterally("kind: $.TypeKind.Function,")
240
+ c.tsw.WriteLine("")
241
+
242
+ // Add parameters
243
+ if funcType.Params() != nil && funcType.Params().Len() > 0 {
244
+ c.tsw.WriteLiterally("params: [")
245
+ for i := 0; i < funcType.Params().Len(); i++ {
246
+ if i > 0 {
247
+ c.tsw.WriteLiterally(", ")
248
+ }
249
+ param := funcType.Params().At(i)
250
+ c.tsw.WriteLiterallyf("'%s'", param.Type().String())
251
+ }
252
+ c.tsw.WriteLiterally("],")
253
+ c.tsw.WriteLine("")
254
+ }
255
+
256
+ // Add results
257
+ if funcType.Results() != nil && funcType.Results().Len() > 0 {
258
+ c.tsw.WriteLiterally("results: [")
259
+ for i := 0; i < funcType.Results().Len(); i++ {
260
+ if i > 0 {
261
+ c.tsw.WriteLiterally(", ")
262
+ }
263
+ result := funcType.Results().At(i)
264
+ c.tsw.WriteLiterallyf("'%s'", result.Type().String())
265
+ }
266
+ c.tsw.WriteLiterally("],")
267
+ c.tsw.WriteLine("")
268
+ }
269
+
270
+ // Add variadic flag
271
+ if funcType.Variadic() {
272
+ c.tsw.WriteLiterally("isVariadic: true,")
273
+ c.tsw.WriteLine("")
274
+ }
275
+
276
+ c.tsw.Indent(-1)
277
+ c.tsw.WriteLiterally("}")
278
+ c.tsw.WriteLine("")
279
+
186
280
  return nil
187
281
  }
188
282
 
@@ -118,7 +118,7 @@ func (c *PackageCompiler) copyProtobufTSFile(sourcePath, fileName string) error
118
118
  }
119
119
 
120
120
  // writeProtobufExports writes exports for a protobuf file to the index.ts file
121
- func (c *PackageCompiler) writeProtobufExports(indexFile *os.File, fileName, pbTsFileName string) error {
121
+ func (c *PackageCompiler) writeProtobufExports(indexFile *os.File, fileName string) error {
122
122
  // For protobuf files, we know they typically export message types
123
123
  // For now, we'll use a simple heuristic: export all types that end with "Msg"
124
124
  // In a full implementation, we would parse the .pb.ts file to extract actual exports
@@ -230,7 +230,7 @@ func (c *GoToTSCompiler) writeProtobufMarshalAssignment(lhs []ast.Expr, callExpr
230
230
 
231
231
  // writeProtobufUnmarshalAssignment handles: err = out.UnmarshalVT(data)
232
232
  // Generates: out = ExampleMsg.fromBinary(data); err = null;
233
- func (c *GoToTSCompiler) writeProtobufUnmarshalAssignment(lhs []ast.Expr, callExpr *ast.CallExpr, tok token.Token) error {
233
+ func (c *GoToTSCompiler) writeProtobufUnmarshalAssignment(lhs []ast.Expr, callExpr *ast.CallExpr) error {
234
234
  if len(lhs) != 1 {
235
235
  return fmt.Errorf("protobuf unmarshal assignment requires exactly 1 LHS variable, got %d", len(lhs))
236
236
  }
@@ -233,14 +233,14 @@ func (c *GoToTSCompiler) WriteValueSpec(a *ast.ValueSpec) error {
233
233
  if c.hasReceiverMethods(typeName) {
234
234
  // Check if the initializer is a basic literal or simple value that needs wrapping
235
235
  needsConstructor := false
236
- switch initializerExpr.(type) {
236
+ switch expr := initializerExpr.(type) {
237
237
  case *ast.BasicLit:
238
238
  needsConstructor = true
239
239
  case *ast.Ident:
240
240
  // Check if it's a simple identifier (not a function call or complex expression)
241
- if ident := initializerExpr.(*ast.Ident); ident.Name != "nil" {
241
+ if expr.Name != "nil" {
242
242
  // Check if this identifier refers to a value of the underlying type
243
- if obj := c.pkg.TypesInfo.Uses[ident]; obj != nil {
243
+ if obj := c.pkg.TypesInfo.Uses[expr]; obj != nil {
244
244
  if objType := obj.Type(); objType != nil {
245
245
  // If the identifier's type matches the underlying type, wrap it
246
246
  if types.Identical(objType, namedType.Underlying()) {
package/compiler/spec.go CHANGED
@@ -45,7 +45,10 @@ func (c *GoToTSCompiler) getEmbeddedFieldKeyName(fieldType types.Type) string {
45
45
  return named.Obj().Name()
46
46
  } else {
47
47
  // Fallback for unnamed embedded types, though less common for structs
48
- fieldKeyName := strings.Title(trueType.String()) // Simple heuristic
48
+ fieldKeyName := trueType.String()
49
+ if len(fieldKeyName) > 0 {
50
+ fieldKeyName = strings.ToUpper(fieldKeyName[:1]) + fieldKeyName[1:]
51
+ }
49
52
  if dotIndex := strings.LastIndex(fieldKeyName, "."); dotIndex != -1 {
50
53
  fieldKeyName = fieldKeyName[dotIndex+1:]
51
54
  }
@@ -261,7 +264,7 @@ func (c *GoToTSCompiler) WriteNamedTypeWithMethods(a *ast.TypeSpec) error {
261
264
 
262
265
  if recvTypeName == className {
263
266
  c.tsw.WriteLine("")
264
- if err := c.writeNamedTypeMethod(funcDecl, className); err != nil {
267
+ if err := c.writeNamedTypeMethod(funcDecl); err != nil {
265
268
  return err
266
269
  }
267
270
  }
@@ -275,7 +278,7 @@ func (c *GoToTSCompiler) WriteNamedTypeWithMethods(a *ast.TypeSpec) error {
275
278
  }
276
279
 
277
280
  // writeNamedTypeMethod writes a method for a named type, handling receiver binding properly
278
- func (c *GoToTSCompiler) writeNamedTypeMethod(decl *ast.FuncDecl, className string) error {
281
+ func (c *GoToTSCompiler) writeNamedTypeMethod(decl *ast.FuncDecl) error {
279
282
  if decl.Doc != nil {
280
283
  c.WriteDoc(decl.Doc)
281
284
  }
@@ -469,7 +469,7 @@ func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) error {
469
469
  if callExpr, ok := exp.Rhs[0].(*ast.CallExpr); ok {
470
470
  // Handle protobuf UnmarshalVT: err = out.UnmarshalVT(data)
471
471
  if c.isProtobufMethodCall(callExpr, "UnmarshalVT") {
472
- return c.writeProtobufUnmarshalAssignment(exp.Lhs, callExpr, exp.Tok)
472
+ return c.writeProtobufUnmarshalAssignment(exp.Lhs, callExpr)
473
473
  }
474
474
  // Handle protobuf UnmarshalJSON: err = out.UnmarshalJSON(data)
475
475
  if c.isProtobufMethodCall(callExpr, "UnmarshalJSON") {
@@ -34,3 +34,48 @@ export declare function normalizeBytes(bytes: Uint8Array | number[] | null | und
34
34
  * @param s The slice to sort in place
35
35
  */
36
36
  export declare function sortSlice<T extends string | number>(s: Slice<T>): void;
37
+ /**
38
+ * bytesEqual efficiently compares two byte slices for equality.
39
+ * Optimized for different byte representations.
40
+ */
41
+ export declare function bytesEqual(a: Bytes | null, b: Bytes | null): boolean;
42
+ /**
43
+ * bytesCompare compares two byte slices lexicographically.
44
+ * Returns -1 if a < b, 0 if a == b, +1 if a > b.
45
+ */
46
+ export declare function bytesCompare(a: Bytes | null, b: Bytes | null): number;
47
+ /**
48
+ * bytesToArray converts any Bytes representation to a number array.
49
+ */
50
+ export declare function bytesToArray(bytes: Bytes | null): number[];
51
+ /**
52
+ * bytesToUint8Array converts any Bytes representation to a Uint8Array.
53
+ */
54
+ export declare function bytesToUint8Array(bytes: Bytes | null): Uint8Array;
55
+ /**
56
+ * bytesIndexOf finds the first occurrence of subslice in bytes.
57
+ * Returns -1 if not found.
58
+ */
59
+ export declare function bytesIndexOf(bytes: Bytes | null, subslice: Bytes | null): number;
60
+ /**
61
+ * bytesLastIndexOf finds the last occurrence of subslice in bytes.
62
+ * Returns -1 if not found.
63
+ */
64
+ export declare function bytesLastIndexOf(bytes: Bytes | null, subslice: Bytes | null): number;
65
+ /**
66
+ * bytesIndexByte finds the first occurrence of byte c in bytes.
67
+ * Returns -1 if not found.
68
+ */
69
+ export declare function bytesIndexByte(bytes: Bytes | null, c: number): number;
70
+ /**
71
+ * bytesLastIndexByte finds the last occurrence of byte c in bytes.
72
+ * Returns -1 if not found.
73
+ */
74
+ export declare function bytesLastIndexByte(bytes: Bytes | null, c: number): number;
75
+ /**
76
+ * bytesCount counts non-overlapping instances of sep in bytes.
77
+ */
78
+ export declare function bytesCount(bytes: Bytes | null, sep: Bytes | null): number;
79
+ export declare function min(a: number, b: number): number;
80
+ export declare function max(a: number, b: number): number;
81
+ export declare function recover(): any;