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.
- package/compiler/analysis.go +129 -8
- package/compiler/compiler.go +4 -1
- package/compiler/composite-lit.go +2 -4
- package/compiler/expr-call.go +12 -0
- package/compiler/lit.go +100 -6
- package/compiler/protobuf.go +2 -2
- package/compiler/spec-value.go +3 -3
- package/compiler/spec.go +6 -3
- package/compiler/stmt-assign.go +1 -1
- package/dist/gs/builtin/builtin.d.ts +45 -0
- package/dist/gs/builtin/builtin.js +197 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.js +2 -1
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.d.ts +56 -0
- package/dist/gs/bytes/buffer.gs.js +611 -0
- package/dist/gs/bytes/buffer.gs.js.map +1 -0
- package/dist/gs/bytes/bytes.gs.d.ts +78 -0
- package/dist/gs/bytes/bytes.gs.js +1011 -0
- package/dist/gs/bytes/bytes.gs.js.map +1 -0
- package/dist/gs/bytes/index.d.ts +4 -0
- package/dist/gs/bytes/index.js +5 -0
- package/dist/gs/bytes/index.js.map +1 -0
- package/dist/gs/bytes/iter.gs.d.ts +9 -0
- package/dist/gs/bytes/iter.gs.js +143 -0
- package/dist/gs/bytes/iter.gs.js.map +1 -0
- package/dist/gs/bytes/reader.gs.d.ts +34 -0
- package/dist/gs/bytes/reader.gs.js +198 -0
- package/dist/gs/bytes/reader.gs.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.d.ts +1 -1
- package/dist/gs/github.com/pkg/errors/errors.js +182 -23
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/go113.d.ts +1 -1
- package/dist/gs/github.com/pkg/errors/go113.js +1 -1
- package/dist/gs/github.com/pkg/errors/go113.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/index.d.ts +3 -3
- package/dist/gs/github.com/pkg/errors/index.js +3 -3
- package/dist/gs/github.com/pkg/errors/index.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/stack.d.ts +1 -1
- package/dist/gs/github.com/pkg/errors/stack.js +8 -5
- package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
- package/dist/gs/internal/abi/index.d.ts +20 -0
- package/dist/gs/internal/abi/index.js +20 -0
- package/dist/gs/internal/abi/index.js.map +1 -0
- package/dist/gs/internal/bytealg/index.d.ts +14 -0
- package/dist/gs/internal/bytealg/index.js +139 -0
- package/dist/gs/internal/bytealg/index.js.map +1 -0
- package/dist/gs/internal/byteorder/index.d.ts +1 -1
- package/dist/gs/internal/byteorder/index.js +4 -4
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/math/index.d.ts +44 -44
- package/dist/gs/math/index.js +44 -44
- package/dist/gs/math/index.js.map +1 -1
- package/dist/gs/os/index.d.ts +19 -19
- package/dist/gs/os/index.js +19 -19
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/reflect/deepequal.d.ts +2 -0
- package/dist/gs/reflect/deepequal.js +91 -0
- package/dist/gs/reflect/deepequal.js.map +1 -0
- package/dist/gs/reflect/index.d.ts +8 -0
- package/dist/gs/reflect/index.js +10 -0
- package/dist/gs/reflect/index.js.map +1 -0
- package/dist/gs/reflect/iter.d.ts +4 -0
- package/dist/gs/reflect/iter.js +24 -0
- package/dist/gs/reflect/iter.js.map +1 -0
- package/dist/gs/reflect/map.d.ts +20 -0
- package/dist/gs/reflect/map.js +74 -0
- package/dist/gs/reflect/map.js.map +1 -0
- package/dist/gs/reflect/swapper.d.ts +2 -0
- package/dist/gs/reflect/swapper.js +46 -0
- package/dist/gs/reflect/swapper.js.map +1 -0
- package/dist/gs/reflect/type.d.ts +134 -0
- package/dist/gs/reflect/type.js +825 -0
- package/dist/gs/reflect/type.js.map +1 -0
- package/dist/gs/reflect/types.d.ts +90 -0
- package/dist/gs/reflect/types.js +119 -0
- package/dist/gs/reflect/types.js.map +1 -0
- package/dist/gs/reflect/value.d.ts +13 -0
- package/dist/gs/reflect/value.js +202 -0
- package/dist/gs/reflect/value.js.map +1 -0
- package/dist/gs/reflect/visiblefields.d.ts +4 -0
- package/dist/gs/reflect/visiblefields.js +149 -0
- package/dist/gs/reflect/visiblefields.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +6 -6
- package/dist/gs/strconv/index.js +6 -6
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/index.d.ts +1 -1
- package/dist/gs/strings/index.js +1 -1
- package/dist/gs/strings/index.js.map +1 -1
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/sync/atomic/index.d.ts +4 -4
- package/dist/gs/sync/atomic/index.js +4 -4
- package/dist/gs/sync/atomic/index.js.map +1 -1
- package/dist/gs/syscall/index.d.ts +6 -6
- package/dist/gs/syscall/index.js +34 -28
- package/dist/gs/syscall/index.js.map +1 -1
- package/dist/gs/unicode/utf8/utf8.d.ts +1 -1
- package/dist/gs/unicode/utf8/utf8.js +4 -2
- package/dist/gs/unicode/utf8/utf8.js.map +1 -1
- package/dist/gs/unsafe/unsafe.js.map +1 -1
- package/gs/builtin/builtin.ts +219 -0
- package/gs/builtin/slice.ts +2 -1
- package/gs/bytes/buffer.gs.ts +614 -0
- package/gs/bytes/bytes.gs.ts +1180 -0
- package/gs/bytes/godoc.txt +69 -0
- package/gs/bytes/index.ts +69 -0
- package/gs/bytes/iter.gs.ts +149 -0
- package/gs/bytes/reader.gs.ts +230 -0
- package/gs/github.com/pkg/errors/errors.ts +408 -238
- package/gs/github.com/pkg/errors/go113.ts +5 -6
- package/gs/github.com/pkg/errors/index.ts +12 -3
- package/gs/github.com/pkg/errors/stack.ts +107 -105
- package/gs/internal/abi/index.ts +37 -0
- package/gs/internal/bytealg/index.ts +149 -0
- package/gs/internal/byteorder/index.ts +5 -5
- package/gs/math/abs.gs.test.ts +1 -1
- package/gs/math/acosh.gs.test.ts +4 -2
- package/gs/math/asin.gs.test.ts +1 -1
- package/gs/math/asinh.gs.test.ts +7 -3
- package/gs/math/atan.gs.test.ts +1 -1
- package/gs/math/atan2.gs.test.ts +17 -9
- package/gs/math/atanh.gs.test.ts +1 -1
- package/gs/math/bits.gs.test.ts +1 -1
- package/gs/math/cbrt.gs.test.ts +1 -1
- package/gs/math/const.gs.test.ts +34 -8
- package/gs/math/copysign.gs.test.ts +7 -3
- package/gs/math/dim.gs.test.ts +19 -7
- package/gs/math/erf.gs.test.ts +1 -1
- package/gs/math/erfinv.gs.test.ts +4 -2
- package/gs/math/exp.gs.test.ts +1 -1
- package/gs/math/expm1.gs.test.ts +6 -4
- package/gs/math/floor.gs.test.ts +17 -4
- package/gs/math/fma.gs.test.ts +53 -53
- package/gs/math/frexp.gs.test.ts +112 -117
- package/gs/math/gamma.gs.test.ts +1 -1
- package/gs/math/hypot.gs.test.ts +53 -53
- package/gs/math/index.ts +80 -44
- package/gs/math/j0.gs.test.ts +6 -2
- package/gs/math/j1.gs.test.ts +6 -2
- package/gs/math/jn.gs.test.ts +9 -5
- package/gs/math/ldexp.gs.test.ts +103 -86
- package/gs/math/lgamma.gs.test.ts +10 -10
- package/gs/math/log.gs.test.ts +1 -1
- package/gs/math/log10.gs.test.ts +1 -1
- package/gs/math/log1p.gs.test.ts +2 -2
- package/gs/math/logb.gs.test.ts +1 -1
- package/gs/math/mod.gs.test.ts +2 -2
- package/gs/math/modf.gs.test.ts +7 -7
- package/gs/math/nextafter.gs.test.ts +9 -7
- package/gs/math/pow.gs.test.ts +6 -4
- package/gs/math/pow10.gs.test.ts +1 -1
- package/gs/math/remainder.gs.test.ts +1 -1
- package/gs/math/signbit.gs.test.ts +1 -1
- package/gs/math/sin.gs.test.ts +1 -1
- package/gs/math/sincos.gs.test.ts +33 -14
- package/gs/math/sinh.gs.test.ts +1 -1
- package/gs/math/sqrt.gs.test.ts +1 -1
- package/gs/math/tan.gs.test.ts +3 -3
- package/gs/math/tanh.gs.test.ts +1 -1
- package/gs/os/index.ts +128 -19
- package/gs/reflect/ANALYSIS.md +278 -0
- package/gs/reflect/deepequal.test.ts +41 -0
- package/gs/reflect/deepequal.ts +169 -0
- package/gs/reflect/function-types.test.ts +146 -0
- package/gs/reflect/godoc.txt +67 -0
- package/gs/reflect/index.ts +83 -0
- package/gs/reflect/iter.ts +44 -0
- package/gs/reflect/map.test.ts +30 -0
- package/gs/reflect/map.ts +85 -0
- package/gs/reflect/swapper.ts +52 -0
- package/gs/reflect/type.ts +1016 -0
- package/gs/reflect/types.ts +214 -0
- package/gs/reflect/value.ts +270 -0
- package/gs/reflect/visiblefields.ts +177 -0
- package/gs/strconv/index.ts +39 -6
- package/gs/strings/index.ts +7 -1
- package/gs/strings/replace.ts +1 -9
- package/gs/sync/atomic/index.ts +53 -4
- package/gs/syscall/index.ts +45 -37
- package/gs/unicode/utf8/utf8.ts +8 -5
- package/gs/unsafe/unsafe.ts +1 -1
- package/package.json +2 -1
- package/dist/gs/internal/testlog/index.d.ts +0 -1
- package/dist/gs/internal/testlog/index.js +0 -5
- package/dist/gs/internal/testlog/index.js.map +0 -1
- package/dist/gs/maps/iter.gs.d.ts +0 -7
- package/dist/gs/maps/iter.gs.js +0 -65
- package/dist/gs/maps/iter.gs.js.map +0 -1
- package/dist/gs/maps/maps.gs.d.ts +0 -7
- package/dist/gs/maps/maps.gs.js +0 -79
- package/dist/gs/maps/maps.gs.js.map +0 -1
- package/dist/gs/stringslite/index.d.ts +0 -1
- package/dist/gs/stringslite/index.js +0 -2
- package/dist/gs/stringslite/index.js.map +0 -1
- package/dist/gs/stringslite/strings.d.ts +0 -11
- package/dist/gs/stringslite/strings.js +0 -67
- package/dist/gs/stringslite/strings.js.map +0 -1
- package/gs/internal/testlog/index.ts +0 -7
package/compiler/analysis.go
CHANGED
|
@@ -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:
|
|
106
|
-
Imports:
|
|
107
|
-
FunctionData:
|
|
108
|
-
NodeData:
|
|
109
|
-
FuncLitData:
|
|
110
|
-
|
|
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
|
+
}
|
package/compiler/compiler.go
CHANGED
|
@@ -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 :=
|
|
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
|
-
|
|
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
|
}
|
package/compiler/expr-call.go
CHANGED
|
@@ -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
|
|
73
|
+
// This is a Go raw string
|
|
74
74
|
content := value[1 : len(value)-1] // Remove surrounding backticks
|
|
75
75
|
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
package/compiler/protobuf.go
CHANGED
|
@@ -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
|
|
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
|
|
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
|
}
|
package/compiler/spec-value.go
CHANGED
|
@@ -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
|
|
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[
|
|
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 :=
|
|
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
|
|
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
|
|
281
|
+
func (c *GoToTSCompiler) writeNamedTypeMethod(decl *ast.FuncDecl) error {
|
|
279
282
|
if decl.Doc != nil {
|
|
280
283
|
c.WriteDoc(decl.Doc)
|
|
281
284
|
}
|
package/compiler/stmt-assign.go
CHANGED
|
@@ -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
|
|
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;
|