goscript 0.0.17 → 0.0.19
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/LICENSE +1 -1
- package/README.md +3 -1
- package/builtin/builtin.ts +323 -45
- package/compiler/compiler.go +541 -80
- package/compiler/compiler_test.go +1 -1
- package/dist/builtin/builtin.d.ts +79 -6
- package/dist/builtin/builtin.js +228 -37
- package/dist/builtin/builtin.js.map +1 -1
- package/package.json +1 -1
package/compiler/compiler.go
CHANGED
|
@@ -303,20 +303,7 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type) {
|
|
|
303
303
|
case *types.Signature:
|
|
304
304
|
c.WriteSignatureType(t)
|
|
305
305
|
case *types.Struct:
|
|
306
|
-
|
|
307
|
-
c.tsw.WriteLiterally("{ ")
|
|
308
|
-
// Add field properties to the interface
|
|
309
|
-
if t.NumFields() > 0 {
|
|
310
|
-
for i := 0; i < t.NumFields(); i++ {
|
|
311
|
-
field := t.Field(i)
|
|
312
|
-
if i > 0 {
|
|
313
|
-
c.tsw.WriteLiterally("; ")
|
|
314
|
-
}
|
|
315
|
-
c.tsw.WriteLiterally(field.Name() + "?: ")
|
|
316
|
-
c.WriteGoType(field.Type())
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
c.tsw.WriteLiterally(" }")
|
|
306
|
+
c.WriteStructType(t)
|
|
320
307
|
default:
|
|
321
308
|
// For other types, just write "any" and add a comment
|
|
322
309
|
c.tsw.WriteLiterally("any")
|
|
@@ -641,6 +628,18 @@ func (c *GoToTSCompiler) WriteZeroValueForType(typ any) {
|
|
|
641
628
|
default:
|
|
642
629
|
c.tsw.WriteLiterally("0")
|
|
643
630
|
}
|
|
631
|
+
case *types.Named:
|
|
632
|
+
// Handle named types, especially struct types
|
|
633
|
+
if _, isStruct := t.Underlying().(*types.Struct); isStruct {
|
|
634
|
+
// Initialize struct types with a new instance
|
|
635
|
+
c.tsw.WriteLiterallyf("new %s()", t.Obj().Name())
|
|
636
|
+
return
|
|
637
|
+
}
|
|
638
|
+
// For other named types, use the zero value of the underlying type
|
|
639
|
+
c.WriteZeroValueForType(t.Underlying())
|
|
640
|
+
case *types.Struct:
|
|
641
|
+
// For anonymous struct types, initialize with {}
|
|
642
|
+
c.tsw.WriteLiterally("{}")
|
|
644
643
|
default:
|
|
645
644
|
c.tsw.WriteLiterally("null")
|
|
646
645
|
}
|
|
@@ -752,6 +751,20 @@ func (c *GoToTSCompiler) WriteValueExpr(a ast.Expr) error {
|
|
|
752
751
|
c.tsw.WriteLiterally(")")
|
|
753
752
|
return nil
|
|
754
753
|
case *ast.ParenExpr:
|
|
754
|
+
// Check if this is a nil pointer to struct type cast: (*struct{})(nil)
|
|
755
|
+
if starExpr, isStarExpr := exp.X.(*ast.StarExpr); isStarExpr {
|
|
756
|
+
if _, isStructType := starExpr.X.(*ast.StructType); isStructType {
|
|
757
|
+
c.tsw.WriteLiterally("null")
|
|
758
|
+
return nil
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Check if this is a type cast with nil: (SomeType)(nil)
|
|
763
|
+
if ident, isIdent := exp.X.(*ast.Ident); isIdent && ident.Name == "nil" {
|
|
764
|
+
c.tsw.WriteLiterally("null")
|
|
765
|
+
return nil
|
|
766
|
+
}
|
|
767
|
+
|
|
755
768
|
// Translate (X) to (X)
|
|
756
769
|
// If we haven't written anything in this statement yet, prepend ;
|
|
757
770
|
c.tsw.WriteLiterally("(")
|
|
@@ -810,9 +823,6 @@ func (c *GoToTSCompiler) WriteIndexExpr(exp *ast.IndexExpr) error {
|
|
|
810
823
|
// context, we expect the asserted value directly. The `TypeName` string is used
|
|
811
824
|
// by the runtime for error messages.
|
|
812
825
|
func (c *GoToTSCompiler) WriteTypeAssertExpr(exp *ast.TypeAssertExpr) error {
|
|
813
|
-
// Get the type name string for the asserted type
|
|
814
|
-
typeName := c.getTypeNameString(exp.Type)
|
|
815
|
-
|
|
816
826
|
// Generate a call to $.typeAssert
|
|
817
827
|
c.tsw.WriteLiterally("$.typeAssert<")
|
|
818
828
|
c.WriteTypeExpr(exp.Type) // Write the asserted type for the generic
|
|
@@ -821,8 +831,23 @@ func (c *GoToTSCompiler) WriteTypeAssertExpr(exp *ast.TypeAssertExpr) error {
|
|
|
821
831
|
return fmt.Errorf("failed to write interface expression in type assertion expression: %w", err)
|
|
822
832
|
}
|
|
823
833
|
c.tsw.WriteLiterally(", ")
|
|
824
|
-
|
|
825
|
-
|
|
834
|
+
|
|
835
|
+
// Write the type description instead of just the type name
|
|
836
|
+
// This ensures we generate proper type info objects for all types
|
|
837
|
+
|
|
838
|
+
// Unwrap parenthesized expressions to handle cases like r.((<-chan T))
|
|
839
|
+
typeExpr := exp.Type
|
|
840
|
+
for {
|
|
841
|
+
if parenExpr, ok := typeExpr.(*ast.ParenExpr); ok {
|
|
842
|
+
typeExpr = parenExpr.X
|
|
843
|
+
} else {
|
|
844
|
+
break
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
c.writeTypeDescription(typeExpr)
|
|
849
|
+
|
|
850
|
+
c.tsw.WriteLiterally(")") // Just close the parenthesis, don't access .value directly
|
|
826
851
|
return nil
|
|
827
852
|
}
|
|
828
853
|
|
|
@@ -1087,17 +1112,19 @@ func (c *GoToTSCompiler) WriteStarExpr(exp *ast.StarExpr) error {
|
|
|
1087
1112
|
// `WriteFieldList` to generate the list of field definitions.
|
|
1088
1113
|
// Note: This is for anonymous struct type literals. Named struct types are usually
|
|
1089
1114
|
// handled as classes via `WriteTypeSpec`.
|
|
1090
|
-
func (c *GoToTSCompiler) WriteStructType(
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1115
|
+
func (c *GoToTSCompiler) WriteStructType(t *types.Struct) {
|
|
1116
|
+
// Generate an interface with the struct's fields
|
|
1117
|
+
c.tsw.WriteLiterally("{ ")
|
|
1118
|
+
// Add field properties to the interface
|
|
1119
|
+
for i := range t.NumFields() {
|
|
1120
|
+
field := t.Field(i)
|
|
1121
|
+
if i > 0 {
|
|
1122
|
+
c.tsw.WriteLiterally("; ")
|
|
1123
|
+
}
|
|
1124
|
+
c.tsw.WriteLiterally(field.Name() + "?: ")
|
|
1125
|
+
c.WriteGoType(field.Type())
|
|
1099
1126
|
}
|
|
1100
|
-
c.
|
|
1127
|
+
c.tsw.WriteLiterally(" }")
|
|
1101
1128
|
}
|
|
1102
1129
|
|
|
1103
1130
|
// WriteFuncType translates a Go function type (`ast.FuncType`) into a TypeScript
|
|
@@ -1175,6 +1202,22 @@ func (c *GoToTSCompiler) WriteFuncType(exp *ast.FuncType, isAsync bool) {
|
|
|
1175
1202
|
func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
1176
1203
|
expFun := exp.Fun
|
|
1177
1204
|
|
|
1205
|
+
// Handle any type conversion with nil argument
|
|
1206
|
+
if len(exp.Args) == 1 {
|
|
1207
|
+
if nilIdent, isIdent := exp.Args[0].(*ast.Ident); isIdent && nilIdent.Name == "nil" {
|
|
1208
|
+
// Handle nil pointer to struct type conversions: (*struct{})(nil)
|
|
1209
|
+
if starExpr, isStarExpr := expFun.(*ast.StarExpr); isStarExpr {
|
|
1210
|
+
if _, isStructType := starExpr.X.(*ast.StructType); isStructType {
|
|
1211
|
+
c.tsw.WriteLiterally("null")
|
|
1212
|
+
return nil
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
c.tsw.WriteLiterally("null")
|
|
1217
|
+
return nil
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1178
1221
|
// Handle array type conversions like []rune(string)
|
|
1179
1222
|
if arrayType, isArrayType := expFun.(*ast.ArrayType); isArrayType {
|
|
1180
1223
|
// Check if it's a []rune type
|
|
@@ -1270,7 +1313,26 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
|
1270
1313
|
c.tsw.WriteLiterally(", ") // Add comma for zero value argument
|
|
1271
1314
|
|
|
1272
1315
|
// Write the zero value for the channel's element type
|
|
1273
|
-
|
|
1316
|
+
if chanType.Elem().String() == "struct{}" {
|
|
1317
|
+
c.tsw.WriteLiterally("{}")
|
|
1318
|
+
} else {
|
|
1319
|
+
c.WriteZeroValueForType(chanType.Elem())
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
// Add direction parameter
|
|
1323
|
+
c.tsw.WriteLiterally(", ")
|
|
1324
|
+
|
|
1325
|
+
// Determine channel direction
|
|
1326
|
+
switch chanType.Dir() {
|
|
1327
|
+
case types.SendRecv:
|
|
1328
|
+
c.tsw.WriteLiterally("'both'")
|
|
1329
|
+
case types.SendOnly:
|
|
1330
|
+
c.tsw.WriteLiterally("'send'")
|
|
1331
|
+
case types.RecvOnly:
|
|
1332
|
+
c.tsw.WriteLiterally("'receive'")
|
|
1333
|
+
default:
|
|
1334
|
+
c.tsw.WriteLiterally("'both'") // Default to bidirectional
|
|
1335
|
+
}
|
|
1274
1336
|
|
|
1275
1337
|
c.tsw.WriteLiterally(")")
|
|
1276
1338
|
return nil // Handled make for channel
|
|
@@ -1431,6 +1493,42 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
|
1431
1493
|
}
|
|
1432
1494
|
return errors.New("unhandled byte call with incorrect number of arguments")
|
|
1433
1495
|
default:
|
|
1496
|
+
// Check if this is a type conversion to a function type
|
|
1497
|
+
if funIdent != nil {
|
|
1498
|
+
if obj := c.pkg.TypesInfo.Uses[funIdent]; obj != nil {
|
|
1499
|
+
// Check if the object is a type name
|
|
1500
|
+
if typeName, isType := obj.(*types.TypeName); isType {
|
|
1501
|
+
// Make sure we have exactly one argument
|
|
1502
|
+
if len(exp.Args) == 1 {
|
|
1503
|
+
// Check if this is a function type
|
|
1504
|
+
if _, isFuncType := typeName.Type().Underlying().(*types.Signature); isFuncType {
|
|
1505
|
+
// For function types, we need to add a __goTypeName property
|
|
1506
|
+
c.tsw.WriteLiterally("Object.assign(")
|
|
1507
|
+
|
|
1508
|
+
// Write the argument first
|
|
1509
|
+
if err := c.WriteValueExpr(exp.Args[0]); err != nil {
|
|
1510
|
+
return fmt.Errorf("failed to write argument for function type cast: %w", err)
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
// Add the __goTypeName property with the function type name
|
|
1514
|
+
c.tsw.WriteLiterallyf(", { __goTypeName: '%s' })", funIdent.String())
|
|
1515
|
+
return nil // Handled function type cast
|
|
1516
|
+
} else {
|
|
1517
|
+
// For non-function types, use the TypeScript "as" operator
|
|
1518
|
+
c.tsw.WriteLiterally("(")
|
|
1519
|
+
if err := c.WriteValueExpr(exp.Args[0]); err != nil {
|
|
1520
|
+
return fmt.Errorf("failed to write argument for type cast: %w", err)
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
// Then use the TypeScript "as" operator with the type name
|
|
1524
|
+
c.tsw.WriteLiterallyf(" as %s)", funIdent.String())
|
|
1525
|
+
return nil // Handled non-function type cast
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1434
1532
|
// Check if this is an async function call
|
|
1435
1533
|
if funIdent != nil {
|
|
1436
1534
|
// Get the object for this function identifier
|
|
@@ -1444,6 +1542,15 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
|
1444
1542
|
if err := c.WriteValueExpr(expFun); err != nil {
|
|
1445
1543
|
return fmt.Errorf("failed to write function expression in call: %w", err)
|
|
1446
1544
|
}
|
|
1545
|
+
|
|
1546
|
+
if funType := c.pkg.TypesInfo.TypeOf(expFun); funType != nil {
|
|
1547
|
+
if _, ok := funType.Underlying().(*types.Signature); ok {
|
|
1548
|
+
if _, isNamed := funType.(*types.Named); isNamed {
|
|
1549
|
+
c.tsw.WriteLiterally("!")
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1447
1554
|
c.tsw.WriteLiterally("(")
|
|
1448
1555
|
for i, arg := range exp.Args {
|
|
1449
1556
|
if i != 0 {
|
|
@@ -1461,6 +1568,14 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
|
1461
1568
|
if err := c.WriteValueExpr(expFun); err != nil {
|
|
1462
1569
|
return fmt.Errorf("failed to write method expression in call: %w", err)
|
|
1463
1570
|
}
|
|
1571
|
+
|
|
1572
|
+
if funType := c.pkg.TypesInfo.TypeOf(expFun); funType != nil {
|
|
1573
|
+
if _, ok := funType.Underlying().(*types.Signature); ok {
|
|
1574
|
+
if _, isNamed := funType.(*types.Named); isNamed {
|
|
1575
|
+
c.tsw.WriteLiterally("!")
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1464
1579
|
}
|
|
1465
1580
|
c.tsw.WriteLiterally("(")
|
|
1466
1581
|
for i, arg := range exp.Args {
|
|
@@ -2744,6 +2859,21 @@ func (c *GoToTSCompiler) WriteValueSpec(a *ast.ValueSpec) error {
|
|
|
2744
2859
|
var initializerExpr ast.Expr
|
|
2745
2860
|
if hasInitializer {
|
|
2746
2861
|
initializerExpr = a.Values[0]
|
|
2862
|
+
|
|
2863
|
+
// Special case for nil pointer to struct type: (*struct{})(nil)
|
|
2864
|
+
if callExpr, isCallExpr := initializerExpr.(*ast.CallExpr); isCallExpr {
|
|
2865
|
+
if starExpr, isStarExpr := callExpr.Fun.(*ast.StarExpr); isStarExpr {
|
|
2866
|
+
if _, isStructType := starExpr.X.(*ast.StructType); isStructType {
|
|
2867
|
+
// Check if the argument is nil
|
|
2868
|
+
if len(callExpr.Args) == 1 {
|
|
2869
|
+
if nilIdent, isIdent := callExpr.Args[0].(*ast.Ident); isIdent && nilIdent.Name == "nil" {
|
|
2870
|
+
c.tsw.WriteLiterally("null")
|
|
2871
|
+
return nil
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2747
2877
|
}
|
|
2748
2878
|
|
|
2749
2879
|
if needsBox {
|
|
@@ -3017,10 +3147,17 @@ func (c *GoToTSCompiler) WriteFieldList(a *ast.FieldList, isArguments bool) {
|
|
|
3017
3147
|
if i > 0 {
|
|
3018
3148
|
c.tsw.WriteLiterally(", ")
|
|
3019
3149
|
}
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3150
|
+
|
|
3151
|
+
// Handle multiple parameter names for the same type
|
|
3152
|
+
for j, name := range field.Names {
|
|
3153
|
+
if j > 0 {
|
|
3154
|
+
c.tsw.WriteLiterally(", ")
|
|
3155
|
+
}
|
|
3156
|
+
c.tsw.WriteLiterally(name.Name)
|
|
3157
|
+
c.tsw.WriteLiterally(": ")
|
|
3158
|
+
typ := c.pkg.TypesInfo.TypeOf(field.Type)
|
|
3159
|
+
c.WriteGoType(typ)
|
|
3160
|
+
}
|
|
3024
3161
|
}
|
|
3025
3162
|
|
|
3026
3163
|
// Handle the variadic parameter
|
|
@@ -3050,11 +3187,16 @@ func (c *GoToTSCompiler) WriteFieldList(a *ast.FieldList, isArguments bool) {
|
|
|
3050
3187
|
}
|
|
3051
3188
|
|
|
3052
3189
|
if isArguments {
|
|
3053
|
-
// For function parameters, write
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3190
|
+
// For function parameters with multiple names, write each with its type
|
|
3191
|
+
for j, name := range field.Names {
|
|
3192
|
+
if j > 0 {
|
|
3193
|
+
c.tsw.WriteLiterally(", ")
|
|
3194
|
+
}
|
|
3195
|
+
c.tsw.WriteLiterally(name.Name)
|
|
3196
|
+
c.tsw.WriteLiterally(": ")
|
|
3197
|
+
typ := c.pkg.TypesInfo.TypeOf(field.Type)
|
|
3198
|
+
c.WriteGoType(typ) // Use WriteGoType for parameter type
|
|
3199
|
+
}
|
|
3058
3200
|
} else {
|
|
3059
3201
|
// For struct fields and other non-argument fields
|
|
3060
3202
|
c.WriteField(field, false)
|
|
@@ -3100,7 +3242,11 @@ func (c *GoToTSCompiler) WriteField(field *ast.Field, isArguments bool) {
|
|
|
3100
3242
|
return
|
|
3101
3243
|
}
|
|
3102
3244
|
|
|
3103
|
-
for
|
|
3245
|
+
for i, name := range field.Names {
|
|
3246
|
+
if i > 0 && isArguments {
|
|
3247
|
+
c.tsw.WriteLiterally(", ")
|
|
3248
|
+
}
|
|
3249
|
+
|
|
3104
3250
|
// argument names: keep original casing, no access modifier
|
|
3105
3251
|
if isArguments {
|
|
3106
3252
|
c.tsw.WriteLiterally(name.Name)
|
|
@@ -3198,6 +3344,10 @@ func (c *GoToTSCompiler) WriteStmt(a ast.Stmt) error {
|
|
|
3198
3344
|
if err := c.WriteValueSpec(valueSpec); err != nil {
|
|
3199
3345
|
return fmt.Errorf("failed to write value spec in declaration statement: %w", err)
|
|
3200
3346
|
}
|
|
3347
|
+
} else if typeSpec, ok := spec.(*ast.TypeSpec); ok {
|
|
3348
|
+
if err := c.WriteTypeSpec(typeSpec); err != nil {
|
|
3349
|
+
return fmt.Errorf("failed to write type spec in declaration statement: %w", err)
|
|
3350
|
+
}
|
|
3201
3351
|
} else {
|
|
3202
3352
|
c.tsw.WriteCommentLinef("unhandled spec in DeclStmt: %T", spec)
|
|
3203
3353
|
}
|
|
@@ -4462,8 +4612,61 @@ func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) error {
|
|
|
4462
4612
|
}
|
|
4463
4613
|
}
|
|
4464
4614
|
|
|
4465
|
-
|
|
4466
|
-
//
|
|
4615
|
+
|
|
4616
|
+
// First, collect all the selector expressions to identify variables that need to be initialized
|
|
4617
|
+
hasSelectors := false
|
|
4618
|
+
for _, lhsExpr := range lhs {
|
|
4619
|
+
if _, ok := lhsExpr.(*ast.SelectorExpr); ok {
|
|
4620
|
+
hasSelectors = true
|
|
4621
|
+
break
|
|
4622
|
+
}
|
|
4623
|
+
}
|
|
4624
|
+
|
|
4625
|
+
// If we have selector expressions, we need to ensure variables are initialized
|
|
4626
|
+
// before the destructuring assignment
|
|
4627
|
+
if hasSelectors {
|
|
4628
|
+
c.tsw.WriteLiterally("{")
|
|
4629
|
+
c.tsw.WriteLine("")
|
|
4630
|
+
|
|
4631
|
+
// Write a temporary variable to hold the function call result
|
|
4632
|
+
c.tsw.WriteLiterally(" const _tmp = ")
|
|
4633
|
+
if err := c.WriteValueExpr(callExpr); err != nil {
|
|
4634
|
+
return fmt.Errorf("failed to write RHS call expression in assignment: %w", err)
|
|
4635
|
+
}
|
|
4636
|
+
c.tsw.WriteLine("")
|
|
4637
|
+
|
|
4638
|
+
for i, lhsExpr := range lhs {
|
|
4639
|
+
// Skip underscore variables
|
|
4640
|
+
if ident, ok := lhsExpr.(*ast.Ident); ok && ident.Name == "_" {
|
|
4641
|
+
continue
|
|
4642
|
+
}
|
|
4643
|
+
|
|
4644
|
+
// Write the LHS with indentation
|
|
4645
|
+
c.tsw.WriteLiterally(" ")
|
|
4646
|
+
if ident, ok := lhsExpr.(*ast.Ident); ok {
|
|
4647
|
+
c.WriteIdent(ident, false)
|
|
4648
|
+
} else if selectorExpr, ok := lhsExpr.(*ast.SelectorExpr); ok {
|
|
4649
|
+
if err := c.WriteValueExpr(selectorExpr); err != nil {
|
|
4650
|
+
return fmt.Errorf("failed to write selector expression in LHS: %w", err)
|
|
4651
|
+
}
|
|
4652
|
+
} else {
|
|
4653
|
+
return errors.Errorf("unhandled LHS expression in assignment: %T", lhsExpr)
|
|
4654
|
+
}
|
|
4655
|
+
|
|
4656
|
+
// Write the assignment
|
|
4657
|
+
c.tsw.WriteLiterallyf(" = _tmp[%d]", i)
|
|
4658
|
+
// Always add a newline after each assignment
|
|
4659
|
+
c.tsw.WriteLine("")
|
|
4660
|
+
}
|
|
4661
|
+
|
|
4662
|
+
// Close the block scope
|
|
4663
|
+
c.tsw.WriteLiterally("}")
|
|
4664
|
+
c.tsw.WriteLine("")
|
|
4665
|
+
|
|
4666
|
+
return nil
|
|
4667
|
+
}
|
|
4668
|
+
|
|
4669
|
+
// For simple cases without selector expressions, use array destructuring
|
|
4467
4670
|
c.tsw.WriteLiterally("[")
|
|
4468
4671
|
|
|
4469
4672
|
for i, lhsExpr := range lhs {
|
|
@@ -4472,11 +4675,15 @@ func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) error {
|
|
|
4472
4675
|
}
|
|
4473
4676
|
|
|
4474
4677
|
if ident, ok := lhsExpr.(*ast.Ident); ok {
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
} else {
|
|
4678
|
+
// For underscore variables, use empty slots in destructuring pattern
|
|
4679
|
+
if ident.Name != "_" {
|
|
4478
4680
|
c.WriteIdent(ident, false)
|
|
4479
4681
|
}
|
|
4682
|
+
} else if selectorExpr, ok := lhsExpr.(*ast.SelectorExpr); ok {
|
|
4683
|
+
// Handle selector expressions (e.g., a.b) by using WriteValueExpr
|
|
4684
|
+
if err := c.WriteValueExpr(selectorExpr); err != nil {
|
|
4685
|
+
return fmt.Errorf("failed to write selector expression in LHS: %w", err)
|
|
4686
|
+
}
|
|
4480
4687
|
} else {
|
|
4481
4688
|
// Should not happen for valid Go code in this context, but handle defensively
|
|
4482
4689
|
return errors.Errorf("unhandled LHS expression in destructuring: %T", lhsExpr)
|
|
@@ -5254,6 +5461,15 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5254
5461
|
interfaceExpr := typeAssertExpr.X
|
|
5255
5462
|
assertedType := typeAssertExpr.Type
|
|
5256
5463
|
|
|
5464
|
+
// Unwrap parenthesized expressions to handle cases like r.((<-chan T))
|
|
5465
|
+
for {
|
|
5466
|
+
if parenExpr, ok := assertedType.(*ast.ParenExpr); ok {
|
|
5467
|
+
assertedType = parenExpr.X
|
|
5468
|
+
} else {
|
|
5469
|
+
break
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
|
|
5257
5473
|
// Ensure LHS has exactly two expressions (value and ok)
|
|
5258
5474
|
if len(lhs) != 2 {
|
|
5259
5475
|
return fmt.Errorf("type assertion assignment requires exactly 2 variables on LHS, got %d", len(lhs))
|
|
@@ -5264,32 +5480,93 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5264
5480
|
okIsBlank := false
|
|
5265
5481
|
var valueName string
|
|
5266
5482
|
var okName string
|
|
5483
|
+
var valueIdent *ast.Ident
|
|
5484
|
+
var okIdent *ast.Ident
|
|
5267
5485
|
|
|
5268
|
-
if
|
|
5269
|
-
|
|
5486
|
+
if valId, ok := lhs[0].(*ast.Ident); ok {
|
|
5487
|
+
valueIdent = valId
|
|
5488
|
+
if valId.Name == "_" {
|
|
5270
5489
|
valueIsBlank = true
|
|
5271
5490
|
} else {
|
|
5272
|
-
valueName =
|
|
5491
|
+
valueName = valId.Name
|
|
5273
5492
|
}
|
|
5274
5493
|
} else {
|
|
5275
5494
|
return fmt.Errorf("unhandled LHS expression type for value in type assertion: %T", lhs[0])
|
|
5276
5495
|
}
|
|
5277
5496
|
|
|
5278
|
-
if
|
|
5279
|
-
|
|
5497
|
+
if okId, ok := lhs[1].(*ast.Ident); ok {
|
|
5498
|
+
okIdent = okId
|
|
5499
|
+
if okId.Name == "_" {
|
|
5280
5500
|
okIsBlank = true
|
|
5281
5501
|
} else {
|
|
5282
|
-
okName =
|
|
5502
|
+
okName = okId.Name
|
|
5283
5503
|
}
|
|
5284
5504
|
} else {
|
|
5285
5505
|
return fmt.Errorf("unhandled LHS expression type for ok in type assertion: %T", lhs[1])
|
|
5286
5506
|
}
|
|
5287
5507
|
|
|
5288
|
-
//
|
|
5508
|
+
// For token.DEFINE (:=), we need to check if any of the variables are already declared
|
|
5509
|
+
// In Go, := can be used for redeclaration if at least one variable is new
|
|
5510
|
+
writeEndParen := false
|
|
5289
5511
|
if tok == token.DEFINE {
|
|
5290
|
-
|
|
5512
|
+
// Identify which variables are new vs existing
|
|
5513
|
+
valueIsNew := true
|
|
5514
|
+
okIsNew := true
|
|
5515
|
+
anyNewVars := false
|
|
5516
|
+
allNewVars := true
|
|
5517
|
+
|
|
5518
|
+
// Check if variables are already in scope
|
|
5519
|
+
if !valueIsBlank {
|
|
5520
|
+
if obj := c.pkg.TypesInfo.Uses[valueIdent]; obj != nil {
|
|
5521
|
+
// If it's in Uses, it's referenced elsewhere, so it exists
|
|
5522
|
+
valueIsNew = false
|
|
5523
|
+
allNewVars = false
|
|
5524
|
+
}
|
|
5525
|
+
if valueIsNew {
|
|
5526
|
+
anyNewVars = true
|
|
5527
|
+
}
|
|
5528
|
+
}
|
|
5529
|
+
|
|
5530
|
+
if !okIsBlank {
|
|
5531
|
+
if obj := c.pkg.TypesInfo.Uses[okIdent]; obj != nil {
|
|
5532
|
+
// If it's in Uses, it's referenced elsewhere, so it exists
|
|
5533
|
+
okIsNew = false
|
|
5534
|
+
allNewVars = false
|
|
5535
|
+
}
|
|
5536
|
+
if okIsNew {
|
|
5537
|
+
anyNewVars = true
|
|
5538
|
+
}
|
|
5539
|
+
}
|
|
5540
|
+
|
|
5541
|
+
if allNewVars && anyNewVars {
|
|
5542
|
+
c.tsw.WriteLiterally("let ")
|
|
5543
|
+
} else if anyNewVars {
|
|
5544
|
+
// If only some variables are new, declare them separately
|
|
5545
|
+
if !valueIsBlank && valueIsNew {
|
|
5546
|
+
c.tsw.WriteLiterally("let ")
|
|
5547
|
+
c.tsw.WriteLiterally(valueName)
|
|
5548
|
+
// Add type annotation if possible
|
|
5549
|
+
if tv, ok := c.pkg.TypesInfo.Types[assertedType]; ok {
|
|
5550
|
+
c.tsw.WriteLiterally(": ")
|
|
5551
|
+
c.WriteGoType(tv.Type)
|
|
5552
|
+
}
|
|
5553
|
+
c.tsw.WriteLine("")
|
|
5554
|
+
}
|
|
5555
|
+
if !okIsBlank && okIsNew {
|
|
5556
|
+
c.tsw.WriteLiterally("let ")
|
|
5557
|
+
c.tsw.WriteLiterally(okName)
|
|
5558
|
+
c.tsw.WriteLiterally(": boolean") // ok is always boolean
|
|
5559
|
+
c.tsw.WriteLine("")
|
|
5560
|
+
}
|
|
5561
|
+
// Use parenthesized destructuring assignment for existing variables
|
|
5562
|
+
c.tsw.WriteLiterally(";(")
|
|
5563
|
+
writeEndParen = true
|
|
5564
|
+
} else {
|
|
5565
|
+
// All variables exist, use parenthesized destructuring assignment
|
|
5566
|
+
c.tsw.WriteLiterally(";(")
|
|
5567
|
+
writeEndParen = true
|
|
5568
|
+
}
|
|
5291
5569
|
} else {
|
|
5292
|
-
// We must wrap in parenthesis.
|
|
5293
5570
|
c.tsw.WriteLiterally("(")
|
|
5294
5571
|
}
|
|
5295
5572
|
|
|
@@ -5383,17 +5660,26 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5383
5660
|
}
|
|
5384
5661
|
|
|
5385
5662
|
if typeExpr.Fields != nil && typeExpr.Fields.List != nil {
|
|
5386
|
-
|
|
5663
|
+
// Add fields property to provide type information
|
|
5664
|
+
c.tsw.WriteLiterally(", fields: {")
|
|
5387
5665
|
|
|
5388
|
-
|
|
5666
|
+
hasFields := false
|
|
5389
5667
|
for _, field := range typeExpr.Fields.List {
|
|
5390
|
-
|
|
5391
|
-
|
|
5668
|
+
if len(field.Names) > 0 {
|
|
5669
|
+
for _, name := range field.Names {
|
|
5670
|
+
if hasFields {
|
|
5671
|
+
c.tsw.WriteLiterally(", ")
|
|
5672
|
+
}
|
|
5673
|
+
c.tsw.WriteLiterally(fmt.Sprintf("'%s': ", name.Name))
|
|
5674
|
+
c.writeTypeDescription(field.Type)
|
|
5675
|
+
hasFields = true
|
|
5676
|
+
}
|
|
5392
5677
|
}
|
|
5393
5678
|
}
|
|
5394
5679
|
|
|
5395
|
-
c.tsw.WriteLiterally(
|
|
5396
|
-
|
|
5680
|
+
c.tsw.WriteLiterally("}")
|
|
5681
|
+
} else {
|
|
5682
|
+
c.tsw.WriteLiterally(", fields: {}")
|
|
5397
5683
|
}
|
|
5398
5684
|
|
|
5399
5685
|
// Add empty methods set to satisfy StructTypeInfo interface
|
|
@@ -5430,8 +5716,11 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5430
5716
|
c.tsw.WriteLiterally("{")
|
|
5431
5717
|
c.tsw.WriteLiterally("kind: $.TypeKind.Pointer")
|
|
5432
5718
|
|
|
5433
|
-
// Add element type if it's a named type
|
|
5434
|
-
if
|
|
5719
|
+
// Add element type if it's a struct type or named type
|
|
5720
|
+
if structType, ok := typeExpr.X.(*ast.StructType); ok {
|
|
5721
|
+
c.tsw.WriteLiterally(", elemType: ")
|
|
5722
|
+
c.writeTypeDescription(structType)
|
|
5723
|
+
} else if ident, ok := typeExpr.X.(*ast.Ident); ok {
|
|
5435
5724
|
c.tsw.WriteLiterallyf(", elemType: '%s'", ident.Name)
|
|
5436
5725
|
}
|
|
5437
5726
|
|
|
@@ -5452,11 +5741,56 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5452
5741
|
c.writeTypeDescription(typeExpr.Value)
|
|
5453
5742
|
}
|
|
5454
5743
|
|
|
5744
|
+
c.tsw.WriteLiterally(", direction: ")
|
|
5745
|
+
switch typeExpr.Dir {
|
|
5746
|
+
case ast.SEND:
|
|
5747
|
+
c.tsw.WriteLiterally("'send'")
|
|
5748
|
+
case ast.RECV:
|
|
5749
|
+
c.tsw.WriteLiterally("'receive'")
|
|
5750
|
+
case ast.SEND | ast.RECV: // bidirectional
|
|
5751
|
+
c.tsw.WriteLiterally("'both'")
|
|
5752
|
+
default:
|
|
5753
|
+
// This should not happen, but just in case
|
|
5754
|
+
c.tsw.WriteLiterally("'both'")
|
|
5755
|
+
}
|
|
5756
|
+
|
|
5455
5757
|
c.tsw.WriteLiterally("}")
|
|
5456
5758
|
case *ast.FuncType:
|
|
5457
|
-
// For function types, create a type descriptor object
|
|
5759
|
+
// For function types, create a type descriptor object with params and results
|
|
5458
5760
|
c.tsw.WriteLiterally("{")
|
|
5459
5761
|
c.tsw.WriteLiterally("kind: $.TypeKind.Function")
|
|
5762
|
+
|
|
5763
|
+
// Add name if this is a named function type
|
|
5764
|
+
if namedType := c.pkg.TypesInfo.TypeOf(typeExpr); namedType != nil {
|
|
5765
|
+
if named, ok := namedType.(*types.Named); ok {
|
|
5766
|
+
c.tsw.WriteLiterallyf(", name: '%s'", named.Obj().Name())
|
|
5767
|
+
}
|
|
5768
|
+
}
|
|
5769
|
+
|
|
5770
|
+
// Add params if present
|
|
5771
|
+
if typeExpr.Params != nil && len(typeExpr.Params.List) > 0 {
|
|
5772
|
+
c.tsw.WriteLiterally(", params: [")
|
|
5773
|
+
for i, param := range typeExpr.Params.List {
|
|
5774
|
+
if i > 0 {
|
|
5775
|
+
c.tsw.WriteLiterally(", ")
|
|
5776
|
+
}
|
|
5777
|
+
c.writeTypeDescription(param.Type)
|
|
5778
|
+
}
|
|
5779
|
+
c.tsw.WriteLiterally("]")
|
|
5780
|
+
}
|
|
5781
|
+
|
|
5782
|
+
// Add results if present
|
|
5783
|
+
if typeExpr.Results != nil && len(typeExpr.Results.List) > 0 {
|
|
5784
|
+
c.tsw.WriteLiterally(", results: [")
|
|
5785
|
+
for i, result := range typeExpr.Results.List {
|
|
5786
|
+
if i > 0 {
|
|
5787
|
+
c.tsw.WriteLiterally(", ")
|
|
5788
|
+
}
|
|
5789
|
+
c.writeTypeDescription(result.Type)
|
|
5790
|
+
}
|
|
5791
|
+
c.tsw.WriteLiterally("]")
|
|
5792
|
+
}
|
|
5793
|
+
|
|
5460
5794
|
c.tsw.WriteLiterally("}")
|
|
5461
5795
|
case *ast.Ident:
|
|
5462
5796
|
if isPrimitiveType(typeExpr.Name) {
|
|
@@ -5472,7 +5806,78 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5472
5806
|
|
|
5473
5807
|
c.tsw.WriteLiterally("}")
|
|
5474
5808
|
} else {
|
|
5475
|
-
|
|
5809
|
+
// Check if this is a named function type
|
|
5810
|
+
isFunctionType := false
|
|
5811
|
+
if namedType := c.pkg.TypesInfo.TypeOf(typeExpr); namedType != nil {
|
|
5812
|
+
if named, ok := namedType.(*types.Named); ok {
|
|
5813
|
+
if _, ok := named.Underlying().(*types.Signature); ok {
|
|
5814
|
+
// This is a named function type, generate a FunctionTypeInfo
|
|
5815
|
+
isFunctionType = true
|
|
5816
|
+
c.tsw.WriteLiterally("{")
|
|
5817
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Function")
|
|
5818
|
+
c.tsw.WriteLiterallyf(", name: '%s'", typeExpr.Name)
|
|
5819
|
+
|
|
5820
|
+
// Get the underlying signature
|
|
5821
|
+
signature := named.Underlying().(*types.Signature)
|
|
5822
|
+
|
|
5823
|
+
// Add params if present
|
|
5824
|
+
params := signature.Params()
|
|
5825
|
+
if params != nil && params.Len() > 0 {
|
|
5826
|
+
c.tsw.WriteLiterally(", params: [")
|
|
5827
|
+
for i := 0; i < params.Len(); i++ {
|
|
5828
|
+
if i > 0 {
|
|
5829
|
+
c.tsw.WriteLiterally(", ")
|
|
5830
|
+
}
|
|
5831
|
+
// Use basic type info for parameters
|
|
5832
|
+
param := params.At(i)
|
|
5833
|
+
c.tsw.WriteLiterally("{")
|
|
5834
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
|
|
5835
|
+
|
|
5836
|
+
typeName := param.Type().String()
|
|
5837
|
+
if tsType, ok := GoBuiltinToTypescript(typeName); ok {
|
|
5838
|
+
c.tsw.WriteLiterallyf("name: '%s'", tsType)
|
|
5839
|
+
} else {
|
|
5840
|
+
c.tsw.WriteLiterallyf("name: '%s'", typeName)
|
|
5841
|
+
}
|
|
5842
|
+
|
|
5843
|
+
c.tsw.WriteLiterally("}")
|
|
5844
|
+
}
|
|
5845
|
+
c.tsw.WriteLiterally("]")
|
|
5846
|
+
}
|
|
5847
|
+
|
|
5848
|
+
// Add results if present
|
|
5849
|
+
results := signature.Results()
|
|
5850
|
+
if results != nil && results.Len() > 0 {
|
|
5851
|
+
c.tsw.WriteLiterally(", results: [")
|
|
5852
|
+
for i := 0; i < results.Len(); i++ {
|
|
5853
|
+
if i > 0 {
|
|
5854
|
+
c.tsw.WriteLiterally(", ")
|
|
5855
|
+
}
|
|
5856
|
+
result := results.At(i)
|
|
5857
|
+
c.tsw.WriteLiterally("{")
|
|
5858
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
|
|
5859
|
+
|
|
5860
|
+
typeName := result.Type().String()
|
|
5861
|
+
if tsType, ok := GoBuiltinToTypescript(typeName); ok {
|
|
5862
|
+
c.tsw.WriteLiterallyf("name: '%s'", tsType)
|
|
5863
|
+
} else {
|
|
5864
|
+
c.tsw.WriteLiterallyf("name: '%s'", typeName)
|
|
5865
|
+
}
|
|
5866
|
+
|
|
5867
|
+
c.tsw.WriteLiterally("}")
|
|
5868
|
+
}
|
|
5869
|
+
c.tsw.WriteLiterally("]")
|
|
5870
|
+
}
|
|
5871
|
+
|
|
5872
|
+
c.tsw.WriteLiterally("}")
|
|
5873
|
+
}
|
|
5874
|
+
}
|
|
5875
|
+
}
|
|
5876
|
+
|
|
5877
|
+
// Default case for non-function named types
|
|
5878
|
+
if !isFunctionType {
|
|
5879
|
+
c.tsw.WriteLiterallyf("'%s'", typeExpr.Name)
|
|
5880
|
+
}
|
|
5476
5881
|
}
|
|
5477
5882
|
case *ast.SelectorExpr:
|
|
5478
5883
|
// For imported types like pkg.Type
|
|
@@ -5489,7 +5894,7 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5489
5894
|
|
|
5490
5895
|
c.tsw.WriteLiterally(")")
|
|
5491
5896
|
|
|
5492
|
-
if tok != token.DEFINE {
|
|
5897
|
+
if tok != token.DEFINE || writeEndParen {
|
|
5493
5898
|
c.tsw.WriteLiterally(")")
|
|
5494
5899
|
}
|
|
5495
5900
|
|
|
@@ -5545,20 +5950,7 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5545
5950
|
|
|
5546
5951
|
// Add field names and types to the struct type info
|
|
5547
5952
|
if t.Fields != nil && t.Fields.List != nil {
|
|
5548
|
-
c.tsw.WriteLiterally("fields:
|
|
5549
|
-
|
|
5550
|
-
fields := []string{}
|
|
5551
|
-
for _, field := range t.Fields.List {
|
|
5552
|
-
for _, name := range field.Names {
|
|
5553
|
-
fields = append(fields, fmt.Sprintf("'%s'", name.Name))
|
|
5554
|
-
}
|
|
5555
|
-
}
|
|
5556
|
-
|
|
5557
|
-
c.tsw.WriteLiterally(strings.Join(fields, ", "))
|
|
5558
|
-
c.tsw.WriteLiterally("]), ")
|
|
5559
|
-
|
|
5560
|
-
// Add fieldTypes property to provide type information
|
|
5561
|
-
c.tsw.WriteLiterally("fieldTypes: {")
|
|
5953
|
+
c.tsw.WriteLiterally("fields: {")
|
|
5562
5954
|
|
|
5563
5955
|
hasFields := false
|
|
5564
5956
|
for _, field := range t.Fields.List {
|
|
@@ -5576,7 +5968,7 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5576
5968
|
|
|
5577
5969
|
c.tsw.WriteLiterally("}, ")
|
|
5578
5970
|
} else {
|
|
5579
|
-
c.tsw.WriteLiterally("fields:
|
|
5971
|
+
c.tsw.WriteLiterally("fields: {}, ")
|
|
5580
5972
|
}
|
|
5581
5973
|
|
|
5582
5974
|
c.tsw.WriteLiterally("methods: new Set()")
|
|
@@ -5596,6 +5988,75 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5596
5988
|
c.tsw.WriteLiterally("kind: $.TypeKind.Pointer, ")
|
|
5597
5989
|
c.tsw.WriteLiterally("elemType: ")
|
|
5598
5990
|
c.writeTypeDescription(t.X)
|
|
5991
|
+
c.tsw.WriteLiterally("}")
|
|
5992
|
+
case *ast.FuncType:
|
|
5993
|
+
// For function types, create a type descriptor object with params and results
|
|
5994
|
+
c.tsw.WriteLiterally("{")
|
|
5995
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Function")
|
|
5996
|
+
|
|
5997
|
+
// Add name if this is a named function type
|
|
5998
|
+
if namedType := c.pkg.TypesInfo.TypeOf(typeExpr); namedType != nil {
|
|
5999
|
+
if named, ok := namedType.(*types.Named); ok {
|
|
6000
|
+
c.tsw.WriteLiterallyf(", name: '%s'", named.Obj().Name())
|
|
6001
|
+
}
|
|
6002
|
+
}
|
|
6003
|
+
|
|
6004
|
+
// Add params if present
|
|
6005
|
+
if t.Params != nil && len(t.Params.List) > 0 {
|
|
6006
|
+
c.tsw.WriteLiterally(", params: [")
|
|
6007
|
+
for i, param := range t.Params.List {
|
|
6008
|
+
if i > 0 {
|
|
6009
|
+
c.tsw.WriteLiterally(", ")
|
|
6010
|
+
}
|
|
6011
|
+
c.writeTypeDescription(param.Type)
|
|
6012
|
+
}
|
|
6013
|
+
c.tsw.WriteLiterally("]")
|
|
6014
|
+
}
|
|
6015
|
+
|
|
6016
|
+
// Add results if present
|
|
6017
|
+
if t.Results != nil && len(t.Results.List) > 0 {
|
|
6018
|
+
c.tsw.WriteLiterally(", results: [")
|
|
6019
|
+
for i, result := range t.Results.List {
|
|
6020
|
+
if i > 0 {
|
|
6021
|
+
c.tsw.WriteLiterally(", ")
|
|
6022
|
+
}
|
|
6023
|
+
c.writeTypeDescription(result.Type)
|
|
6024
|
+
}
|
|
6025
|
+
c.tsw.WriteLiterally("]")
|
|
6026
|
+
}
|
|
6027
|
+
|
|
6028
|
+
c.tsw.WriteLiterally("}")
|
|
6029
|
+
return
|
|
6030
|
+
case *ast.ChanType:
|
|
6031
|
+
c.tsw.WriteLiterally("{")
|
|
6032
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Channel, ")
|
|
6033
|
+
c.tsw.WriteLiterally("elemType: ")
|
|
6034
|
+
|
|
6035
|
+
// Add element type
|
|
6036
|
+
if ident, ok := t.Value.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
6037
|
+
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
6038
|
+
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
6039
|
+
} else {
|
|
6040
|
+
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
6041
|
+
}
|
|
6042
|
+
} else {
|
|
6043
|
+
c.writeTypeDescription(t.Value)
|
|
6044
|
+
}
|
|
6045
|
+
|
|
6046
|
+
// Add direction
|
|
6047
|
+
c.tsw.WriteLiterally(", direction: ")
|
|
6048
|
+
switch t.Dir {
|
|
6049
|
+
case ast.SEND:
|
|
6050
|
+
c.tsw.WriteLiterally("'send'")
|
|
6051
|
+
case ast.RECV:
|
|
6052
|
+
c.tsw.WriteLiterally("'receive'")
|
|
6053
|
+
case ast.SEND | ast.RECV: // bidirectional
|
|
6054
|
+
c.tsw.WriteLiterally("'both'")
|
|
6055
|
+
default:
|
|
6056
|
+
// This should not happen, but just in case
|
|
6057
|
+
c.tsw.WriteLiterally("'both'")
|
|
6058
|
+
}
|
|
6059
|
+
|
|
5599
6060
|
c.tsw.WriteLiterally("}")
|
|
5600
6061
|
default:
|
|
5601
6062
|
// For other types, use the string representation
|