goscript 0.0.16 → 0.0.18
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 +537 -140
- package/compiler/writer.go +14 -0
- package/dist/builtin/builtin.d.ts +79 -6
- package/dist/builtin/builtin.js +228 -37
- package/dist/builtin/builtin.js.map +1 -1
- package/go.mod +1 -3
- package/package.json +1 -1
package/compiler/compiler.go
CHANGED
|
@@ -303,24 +303,11 @@ 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")
|
|
323
|
-
c.tsw.
|
|
310
|
+
c.tsw.WriteCommentInlinef("unhandled type: %T", typ)
|
|
324
311
|
}
|
|
325
312
|
}
|
|
326
313
|
|
|
@@ -452,7 +439,7 @@ func (c *GoToTSCompiler) WriteSignatureType(t *types.Signature) {
|
|
|
452
439
|
if param.Name() != "" {
|
|
453
440
|
c.tsw.WriteLiterally(param.Name())
|
|
454
441
|
} else {
|
|
455
|
-
c.tsw.
|
|
442
|
+
c.tsw.WriteLiterallyf("p%d", i)
|
|
456
443
|
}
|
|
457
444
|
c.tsw.WriteLiterally(": ")
|
|
458
445
|
|
|
@@ -752,6 +739,20 @@ func (c *GoToTSCompiler) WriteValueExpr(a ast.Expr) error {
|
|
|
752
739
|
c.tsw.WriteLiterally(")")
|
|
753
740
|
return nil
|
|
754
741
|
case *ast.ParenExpr:
|
|
742
|
+
// Check if this is a nil pointer to struct type cast: (*struct{})(nil)
|
|
743
|
+
if starExpr, isStarExpr := exp.X.(*ast.StarExpr); isStarExpr {
|
|
744
|
+
if _, isStructType := starExpr.X.(*ast.StructType); isStructType {
|
|
745
|
+
c.tsw.WriteLiterally("null")
|
|
746
|
+
return nil
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// Check if this is a type cast with nil: (SomeType)(nil)
|
|
751
|
+
if ident, isIdent := exp.X.(*ast.Ident); isIdent && ident.Name == "nil" {
|
|
752
|
+
c.tsw.WriteLiterally("null")
|
|
753
|
+
return nil
|
|
754
|
+
}
|
|
755
|
+
|
|
755
756
|
// Translate (X) to (X)
|
|
756
757
|
// If we haven't written anything in this statement yet, prepend ;
|
|
757
758
|
c.tsw.WriteLiterally("(")
|
|
@@ -763,7 +764,7 @@ func (c *GoToTSCompiler) WriteValueExpr(a ast.Expr) error {
|
|
|
763
764
|
case *ast.FuncLit:
|
|
764
765
|
return c.WriteFuncLitValue(exp)
|
|
765
766
|
default:
|
|
766
|
-
c.tsw.
|
|
767
|
+
c.tsw.WriteCommentLinef("unhandled value expr: %T", exp)
|
|
767
768
|
return nil
|
|
768
769
|
}
|
|
769
770
|
}
|
|
@@ -774,19 +775,19 @@ func (c *GoToTSCompiler) WriteIndexExpr(exp *ast.IndexExpr) error {
|
|
|
774
775
|
if tv, ok := c.pkg.TypesInfo.Types[exp.X]; ok {
|
|
775
776
|
// Check if it's a map type
|
|
776
777
|
if mapType, isMap := tv.Type.Underlying().(*types.Map); isMap {
|
|
778
|
+
c.tsw.WriteLiterally("$.mapGet(")
|
|
777
779
|
if err := c.WriteValueExpr(exp.X); err != nil {
|
|
778
780
|
return err
|
|
779
781
|
}
|
|
780
|
-
c.tsw.WriteLiterally("
|
|
782
|
+
c.tsw.WriteLiterally(", ")
|
|
781
783
|
if err := c.WriteValueExpr(exp.Index); err != nil {
|
|
782
784
|
return err
|
|
783
785
|
}
|
|
784
|
-
|
|
785
|
-
// Add nullish coalescing with the appropriate zero value for the map's value type
|
|
786
|
-
c.tsw.WriteLiterally(") ?? ")
|
|
786
|
+
c.tsw.WriteLiterally(", ")
|
|
787
787
|
|
|
788
|
-
// Generate the zero value
|
|
788
|
+
// Generate the zero value as the default value for mapGet
|
|
789
789
|
c.WriteZeroValueForType(mapType.Elem())
|
|
790
|
+
c.tsw.WriteLiterally(")")
|
|
790
791
|
return nil
|
|
791
792
|
}
|
|
792
793
|
}
|
|
@@ -810,9 +811,6 @@ func (c *GoToTSCompiler) WriteIndexExpr(exp *ast.IndexExpr) error {
|
|
|
810
811
|
// context, we expect the asserted value directly. The `TypeName` string is used
|
|
811
812
|
// by the runtime for error messages.
|
|
812
813
|
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
814
|
// Generate a call to $.typeAssert
|
|
817
815
|
c.tsw.WriteLiterally("$.typeAssert<")
|
|
818
816
|
c.WriteTypeExpr(exp.Type) // Write the asserted type for the generic
|
|
@@ -821,8 +819,23 @@ func (c *GoToTSCompiler) WriteTypeAssertExpr(exp *ast.TypeAssertExpr) error {
|
|
|
821
819
|
return fmt.Errorf("failed to write interface expression in type assertion expression: %w", err)
|
|
822
820
|
}
|
|
823
821
|
c.tsw.WriteLiterally(", ")
|
|
824
|
-
|
|
825
|
-
|
|
822
|
+
|
|
823
|
+
// Write the type description instead of just the type name
|
|
824
|
+
// This ensures we generate proper type info objects for all types
|
|
825
|
+
|
|
826
|
+
// Unwrap parenthesized expressions to handle cases like r.((<-chan T))
|
|
827
|
+
typeExpr := exp.Type
|
|
828
|
+
for {
|
|
829
|
+
if parenExpr, ok := typeExpr.(*ast.ParenExpr); ok {
|
|
830
|
+
typeExpr = parenExpr.X
|
|
831
|
+
} else {
|
|
832
|
+
break
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
c.writeTypeDescription(typeExpr)
|
|
837
|
+
|
|
838
|
+
c.tsw.WriteLiterally(")") // Just close the parenthesis, don't access .value directly
|
|
826
839
|
return nil
|
|
827
840
|
}
|
|
828
841
|
|
|
@@ -1087,17 +1100,19 @@ func (c *GoToTSCompiler) WriteStarExpr(exp *ast.StarExpr) error {
|
|
|
1087
1100
|
// `WriteFieldList` to generate the list of field definitions.
|
|
1088
1101
|
// Note: This is for anonymous struct type literals. Named struct types are usually
|
|
1089
1102
|
// handled as classes via `WriteTypeSpec`.
|
|
1090
|
-
func (c *GoToTSCompiler) WriteStructType(
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1103
|
+
func (c *GoToTSCompiler) WriteStructType(t *types.Struct) {
|
|
1104
|
+
// Generate an interface with the struct's fields
|
|
1105
|
+
c.tsw.WriteLiterally("{ ")
|
|
1106
|
+
// Add field properties to the interface
|
|
1107
|
+
for i := range t.NumFields() {
|
|
1108
|
+
field := t.Field(i)
|
|
1109
|
+
if i > 0 {
|
|
1110
|
+
c.tsw.WriteLiterally("; ")
|
|
1111
|
+
}
|
|
1112
|
+
c.tsw.WriteLiterally(field.Name() + "?: ")
|
|
1113
|
+
c.WriteGoType(field.Type())
|
|
1099
1114
|
}
|
|
1100
|
-
c.
|
|
1115
|
+
c.tsw.WriteLiterally(" }")
|
|
1101
1116
|
}
|
|
1102
1117
|
|
|
1103
1118
|
// WriteFuncType translates a Go function type (`ast.FuncType`) into a TypeScript
|
|
@@ -1175,6 +1190,22 @@ func (c *GoToTSCompiler) WriteFuncType(exp *ast.FuncType, isAsync bool) {
|
|
|
1175
1190
|
func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
1176
1191
|
expFun := exp.Fun
|
|
1177
1192
|
|
|
1193
|
+
// Handle any type conversion with nil argument
|
|
1194
|
+
if len(exp.Args) == 1 {
|
|
1195
|
+
if nilIdent, isIdent := exp.Args[0].(*ast.Ident); isIdent && nilIdent.Name == "nil" {
|
|
1196
|
+
// Handle nil pointer to struct type conversions: (*struct{})(nil)
|
|
1197
|
+
if starExpr, isStarExpr := expFun.(*ast.StarExpr); isStarExpr {
|
|
1198
|
+
if _, isStructType := starExpr.X.(*ast.StructType); isStructType {
|
|
1199
|
+
c.tsw.WriteLiterally("null")
|
|
1200
|
+
return nil
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
c.tsw.WriteLiterally("null")
|
|
1205
|
+
return nil
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1178
1209
|
// Handle array type conversions like []rune(string)
|
|
1179
1210
|
if arrayType, isArrayType := expFun.(*ast.ArrayType); isArrayType {
|
|
1180
1211
|
// Check if it's a []rune type
|
|
@@ -1270,7 +1301,26 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
|
1270
1301
|
c.tsw.WriteLiterally(", ") // Add comma for zero value argument
|
|
1271
1302
|
|
|
1272
1303
|
// Write the zero value for the channel's element type
|
|
1273
|
-
|
|
1304
|
+
if chanType.Elem().String() == "struct{}" {
|
|
1305
|
+
c.tsw.WriteLiterally("{}")
|
|
1306
|
+
} else {
|
|
1307
|
+
c.WriteZeroValueForType(chanType.Elem())
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
// Add direction parameter
|
|
1311
|
+
c.tsw.WriteLiterally(", ")
|
|
1312
|
+
|
|
1313
|
+
// Determine channel direction
|
|
1314
|
+
switch chanType.Dir() {
|
|
1315
|
+
case types.SendRecv:
|
|
1316
|
+
c.tsw.WriteLiterally("'both'")
|
|
1317
|
+
case types.SendOnly:
|
|
1318
|
+
c.tsw.WriteLiterally("'send'")
|
|
1319
|
+
case types.RecvOnly:
|
|
1320
|
+
c.tsw.WriteLiterally("'receive'")
|
|
1321
|
+
default:
|
|
1322
|
+
c.tsw.WriteLiterally("'both'") // Default to bidirectional
|
|
1323
|
+
}
|
|
1274
1324
|
|
|
1275
1325
|
c.tsw.WriteLiterally(")")
|
|
1276
1326
|
return nil // Handled make for channel
|
|
@@ -1431,6 +1481,42 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
|
1431
1481
|
}
|
|
1432
1482
|
return errors.New("unhandled byte call with incorrect number of arguments")
|
|
1433
1483
|
default:
|
|
1484
|
+
// Check if this is a type conversion to a function type
|
|
1485
|
+
if funIdent != nil {
|
|
1486
|
+
if obj := c.pkg.TypesInfo.Uses[funIdent]; obj != nil {
|
|
1487
|
+
// Check if the object is a type name
|
|
1488
|
+
if typeName, isType := obj.(*types.TypeName); isType {
|
|
1489
|
+
// Make sure we have exactly one argument
|
|
1490
|
+
if len(exp.Args) == 1 {
|
|
1491
|
+
// Check if this is a function type
|
|
1492
|
+
if _, isFuncType := typeName.Type().Underlying().(*types.Signature); isFuncType {
|
|
1493
|
+
// For function types, we need to add a __goTypeName property
|
|
1494
|
+
c.tsw.WriteLiterally("Object.assign(")
|
|
1495
|
+
|
|
1496
|
+
// Write the argument first
|
|
1497
|
+
if err := c.WriteValueExpr(exp.Args[0]); err != nil {
|
|
1498
|
+
return fmt.Errorf("failed to write argument for function type cast: %w", err)
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
// Add the __goTypeName property with the function type name
|
|
1502
|
+
c.tsw.WriteLiterallyf(", { __goTypeName: '%s' })", funIdent.String())
|
|
1503
|
+
return nil // Handled function type cast
|
|
1504
|
+
} else {
|
|
1505
|
+
// For non-function types, use the TypeScript "as" operator
|
|
1506
|
+
c.tsw.WriteLiterally("(")
|
|
1507
|
+
if err := c.WriteValueExpr(exp.Args[0]); err != nil {
|
|
1508
|
+
return fmt.Errorf("failed to write argument for type cast: %w", err)
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// Then use the TypeScript "as" operator with the type name
|
|
1512
|
+
c.tsw.WriteLiterallyf(" as %s)", funIdent.String())
|
|
1513
|
+
return nil // Handled non-function type cast
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1434
1520
|
// Check if this is an async function call
|
|
1435
1521
|
if funIdent != nil {
|
|
1436
1522
|
// Get the object for this function identifier
|
|
@@ -1444,6 +1530,15 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
|
1444
1530
|
if err := c.WriteValueExpr(expFun); err != nil {
|
|
1445
1531
|
return fmt.Errorf("failed to write function expression in call: %w", err)
|
|
1446
1532
|
}
|
|
1533
|
+
|
|
1534
|
+
if funType := c.pkg.TypesInfo.TypeOf(expFun); funType != nil {
|
|
1535
|
+
if _, ok := funType.Underlying().(*types.Signature); ok {
|
|
1536
|
+
if _, isNamed := funType.(*types.Named); isNamed {
|
|
1537
|
+
c.tsw.WriteLiterally("!")
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1447
1542
|
c.tsw.WriteLiterally("(")
|
|
1448
1543
|
for i, arg := range exp.Args {
|
|
1449
1544
|
if i != 0 {
|
|
@@ -1461,6 +1556,14 @@ func (c *GoToTSCompiler) WriteCallExpr(exp *ast.CallExpr) error {
|
|
|
1461
1556
|
if err := c.WriteValueExpr(expFun); err != nil {
|
|
1462
1557
|
return fmt.Errorf("failed to write method expression in call: %w", err)
|
|
1463
1558
|
}
|
|
1559
|
+
|
|
1560
|
+
if funType := c.pkg.TypesInfo.TypeOf(expFun); funType != nil {
|
|
1561
|
+
if _, ok := funType.Underlying().(*types.Signature); ok {
|
|
1562
|
+
if _, isNamed := funType.(*types.Named); isNamed {
|
|
1563
|
+
c.tsw.WriteLiterally("!")
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1464
1567
|
}
|
|
1465
1568
|
c.tsw.WriteLiterally("(")
|
|
1466
1569
|
for i, arg := range exp.Args {
|
|
@@ -1709,10 +1812,10 @@ func (c *GoToTSCompiler) WriteBasicLit(exp *ast.BasicLit) {
|
|
|
1709
1812
|
// Use strconv.UnquoteChar to handle escape sequences correctly.
|
|
1710
1813
|
val, _, _, err := strconv.UnquoteChar(exp.Value[1:len(exp.Value)-1], '\'')
|
|
1711
1814
|
if err != nil {
|
|
1712
|
-
c.tsw.
|
|
1815
|
+
c.tsw.WriteCommentInlinef("error parsing char literal %s: %v", exp.Value, err)
|
|
1713
1816
|
c.tsw.WriteLiterally("0") // Default to 0 on error
|
|
1714
1817
|
} else {
|
|
1715
|
-
c.tsw.
|
|
1818
|
+
c.tsw.WriteLiterallyf("%d", val)
|
|
1716
1819
|
}
|
|
1717
1820
|
} else {
|
|
1718
1821
|
// Other literals (INT, FLOAT, STRING, IMAG)
|
|
@@ -2362,7 +2465,7 @@ func (c *GoToTSCompiler) collectMethodNames(structName string) string {
|
|
|
2362
2465
|
// Check if the receiver identifier name matches the struct name
|
|
2363
2466
|
if ident, ok := recvType.(*ast.Ident); ok && ident.Name == structName {
|
|
2364
2467
|
// Found a method for this struct
|
|
2365
|
-
methodNames = append(methodNames,
|
|
2468
|
+
methodNames = append(methodNames, strconv.Quote(funcDecl.Name.Name))
|
|
2366
2469
|
}
|
|
2367
2470
|
}
|
|
2368
2471
|
}
|
|
@@ -2744,6 +2847,21 @@ func (c *GoToTSCompiler) WriteValueSpec(a *ast.ValueSpec) error {
|
|
|
2744
2847
|
var initializerExpr ast.Expr
|
|
2745
2848
|
if hasInitializer {
|
|
2746
2849
|
initializerExpr = a.Values[0]
|
|
2850
|
+
|
|
2851
|
+
// Special case for nil pointer to struct type: (*struct{})(nil)
|
|
2852
|
+
if callExpr, isCallExpr := initializerExpr.(*ast.CallExpr); isCallExpr {
|
|
2853
|
+
if starExpr, isStarExpr := callExpr.Fun.(*ast.StarExpr); isStarExpr {
|
|
2854
|
+
if _, isStructType := starExpr.X.(*ast.StructType); isStructType {
|
|
2855
|
+
// Check if the argument is nil
|
|
2856
|
+
if len(callExpr.Args) == 1 {
|
|
2857
|
+
if nilIdent, isIdent := callExpr.Args[0].(*ast.Ident); isIdent && nilIdent.Name == "nil" {
|
|
2858
|
+
c.tsw.WriteLiterally("null")
|
|
2859
|
+
return nil
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2747
2865
|
}
|
|
2748
2866
|
|
|
2749
2867
|
if needsBox {
|
|
@@ -3017,10 +3135,17 @@ func (c *GoToTSCompiler) WriteFieldList(a *ast.FieldList, isArguments bool) {
|
|
|
3017
3135
|
if i > 0 {
|
|
3018
3136
|
c.tsw.WriteLiterally(", ")
|
|
3019
3137
|
}
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3138
|
+
|
|
3139
|
+
// Handle multiple parameter names for the same type
|
|
3140
|
+
for j, name := range field.Names {
|
|
3141
|
+
if j > 0 {
|
|
3142
|
+
c.tsw.WriteLiterally(", ")
|
|
3143
|
+
}
|
|
3144
|
+
c.tsw.WriteLiterally(name.Name)
|
|
3145
|
+
c.tsw.WriteLiterally(": ")
|
|
3146
|
+
typ := c.pkg.TypesInfo.TypeOf(field.Type)
|
|
3147
|
+
c.WriteGoType(typ)
|
|
3148
|
+
}
|
|
3024
3149
|
}
|
|
3025
3150
|
|
|
3026
3151
|
// Handle the variadic parameter
|
|
@@ -3050,11 +3175,16 @@ func (c *GoToTSCompiler) WriteFieldList(a *ast.FieldList, isArguments bool) {
|
|
|
3050
3175
|
}
|
|
3051
3176
|
|
|
3052
3177
|
if isArguments {
|
|
3053
|
-
// For function parameters, write
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3178
|
+
// For function parameters with multiple names, write each with its type
|
|
3179
|
+
for j, name := range field.Names {
|
|
3180
|
+
if j > 0 {
|
|
3181
|
+
c.tsw.WriteLiterally(", ")
|
|
3182
|
+
}
|
|
3183
|
+
c.tsw.WriteLiterally(name.Name)
|
|
3184
|
+
c.tsw.WriteLiterally(": ")
|
|
3185
|
+
typ := c.pkg.TypesInfo.TypeOf(field.Type)
|
|
3186
|
+
c.WriteGoType(typ) // Use WriteGoType for parameter type
|
|
3187
|
+
}
|
|
3058
3188
|
} else {
|
|
3059
3189
|
// For struct fields and other non-argument fields
|
|
3060
3190
|
c.WriteField(field, false)
|
|
@@ -3100,7 +3230,11 @@ func (c *GoToTSCompiler) WriteField(field *ast.Field, isArguments bool) {
|
|
|
3100
3230
|
return
|
|
3101
3231
|
}
|
|
3102
3232
|
|
|
3103
|
-
for
|
|
3233
|
+
for i, name := range field.Names {
|
|
3234
|
+
if i > 0 && isArguments {
|
|
3235
|
+
c.tsw.WriteLiterally(", ")
|
|
3236
|
+
}
|
|
3237
|
+
|
|
3104
3238
|
// argument names: keep original casing, no access modifier
|
|
3105
3239
|
if isArguments {
|
|
3106
3240
|
c.tsw.WriteLiterally(name.Name)
|
|
@@ -3120,7 +3254,7 @@ func (c *GoToTSCompiler) WriteField(field *ast.Field, isArguments bool) {
|
|
|
3120
3254
|
if !isArguments {
|
|
3121
3255
|
// write tag comment if any for struct fields
|
|
3122
3256
|
if field.Tag != nil {
|
|
3123
|
-
c.tsw.
|
|
3257
|
+
c.tsw.WriteCommentLinef("tag: %s", field.Tag.Value)
|
|
3124
3258
|
} else {
|
|
3125
3259
|
c.tsw.WriteLine("") // No semicolon
|
|
3126
3260
|
}
|
|
@@ -3198,8 +3332,12 @@ func (c *GoToTSCompiler) WriteStmt(a ast.Stmt) error {
|
|
|
3198
3332
|
if err := c.WriteValueSpec(valueSpec); err != nil {
|
|
3199
3333
|
return fmt.Errorf("failed to write value spec in declaration statement: %w", err)
|
|
3200
3334
|
}
|
|
3335
|
+
} else if typeSpec, ok := spec.(*ast.TypeSpec); ok {
|
|
3336
|
+
if err := c.WriteTypeSpec(typeSpec); err != nil {
|
|
3337
|
+
return fmt.Errorf("failed to write type spec in declaration statement: %w", err)
|
|
3338
|
+
}
|
|
3201
3339
|
} else {
|
|
3202
|
-
c.tsw.
|
|
3340
|
+
c.tsw.WriteCommentLinef("unhandled spec in DeclStmt: %T", spec)
|
|
3203
3341
|
}
|
|
3204
3342
|
}
|
|
3205
3343
|
} else {
|
|
@@ -3278,7 +3416,7 @@ func (c *GoToTSCompiler) WriteStmt(a ast.Stmt) error {
|
|
|
3278
3416
|
case token.CONTINUE:
|
|
3279
3417
|
c.tsw.WriteLine("continue") // No semicolon needed
|
|
3280
3418
|
default:
|
|
3281
|
-
c.tsw.
|
|
3419
|
+
c.tsw.WriteCommentLinef("unhandled branch statement token: %s", exp.Tok.String())
|
|
3282
3420
|
}
|
|
3283
3421
|
default:
|
|
3284
3422
|
return errors.Errorf("unknown statement: %s\n", a)
|
|
@@ -3316,7 +3454,7 @@ func (c *GoToTSCompiler) WriteStmtDefer(exp *ast.DeferStmt) error {
|
|
|
3316
3454
|
|
|
3317
3455
|
// Set stack variable based on whether we are in an async function
|
|
3318
3456
|
stackVar := "__defer"
|
|
3319
|
-
c.tsw.
|
|
3457
|
+
c.tsw.WriteLiterallyf("%s.defer(%s() => {", stackVar, asyncPrefix)
|
|
3320
3458
|
c.tsw.Indent(1)
|
|
3321
3459
|
c.tsw.WriteLine("")
|
|
3322
3460
|
|
|
@@ -3418,7 +3556,7 @@ func (c *GoToTSCompiler) WriteStmtSelect(exp *ast.SelectStmt) error {
|
|
|
3418
3556
|
c.tsw.WriteLiterally("{") // Start object literal
|
|
3419
3557
|
c.tsw.Indent(1)
|
|
3420
3558
|
c.tsw.WriteLine("")
|
|
3421
|
-
c.tsw.
|
|
3559
|
+
c.tsw.WriteLiterallyf("id: %d,", caseID)
|
|
3422
3560
|
c.tsw.WriteLine("")
|
|
3423
3561
|
|
|
3424
3562
|
// Handle different types of comm statements
|
|
@@ -3437,10 +3575,10 @@ func (c *GoToTSCompiler) WriteStmtSelect(exp *ast.SelectStmt) error {
|
|
|
3437
3575
|
c.tsw.WriteLiterally(",")
|
|
3438
3576
|
c.tsw.WriteLine("")
|
|
3439
3577
|
} else {
|
|
3440
|
-
c.tsw.
|
|
3578
|
+
c.tsw.WriteCommentLinef("unhandled RHS in select assignment case: %T", comm.Rhs[0])
|
|
3441
3579
|
}
|
|
3442
3580
|
} else {
|
|
3443
|
-
c.tsw.
|
|
3581
|
+
c.tsw.WriteCommentLinef("unhandled RHS count in select assignment case: %d", len(comm.Rhs))
|
|
3444
3582
|
}
|
|
3445
3583
|
case *ast.ExprStmt:
|
|
3446
3584
|
// This is a simple receive: case <-ch:
|
|
@@ -3454,7 +3592,7 @@ func (c *GoToTSCompiler) WriteStmtSelect(exp *ast.SelectStmt) error {
|
|
|
3454
3592
|
c.tsw.WriteLiterally(",")
|
|
3455
3593
|
c.tsw.WriteLine("")
|
|
3456
3594
|
} else {
|
|
3457
|
-
c.tsw.
|
|
3595
|
+
c.tsw.WriteCommentLinef("unhandled expression in select case: %T", comm.X)
|
|
3458
3596
|
}
|
|
3459
3597
|
case *ast.SendStmt:
|
|
3460
3598
|
// This is a send operation: case ch <- v:
|
|
@@ -3473,7 +3611,7 @@ func (c *GoToTSCompiler) WriteStmtSelect(exp *ast.SelectStmt) error {
|
|
|
3473
3611
|
c.tsw.WriteLiterally(",")
|
|
3474
3612
|
c.tsw.WriteLine("")
|
|
3475
3613
|
default:
|
|
3476
|
-
c.tsw.
|
|
3614
|
+
c.tsw.WriteCommentLinef("unhandled comm statement in select case: %T", comm)
|
|
3477
3615
|
}
|
|
3478
3616
|
|
|
3479
3617
|
// Add the onSelected handler to execute the case body after the select resolves
|
|
@@ -3530,14 +3668,14 @@ func (c *GoToTSCompiler) WriteStmtSelect(exp *ast.SelectStmt) error {
|
|
|
3530
3668
|
c.tsw.WriteLine("")
|
|
3531
3669
|
|
|
3532
3670
|
} else {
|
|
3533
|
-
c.tsw.
|
|
3671
|
+
c.tsw.WriteCommentLinef("unknown statement in select body: %T", stmt)
|
|
3534
3672
|
}
|
|
3535
3673
|
}
|
|
3536
3674
|
|
|
3537
3675
|
// Close the array literal and the selectStatement call
|
|
3538
3676
|
c.tsw.Indent(-1)
|
|
3539
3677
|
c.tsw.WriteLiterally("], ")
|
|
3540
|
-
c.tsw.
|
|
3678
|
+
c.tsw.WriteLiterallyf("%t", hasDefault)
|
|
3541
3679
|
c.tsw.WriteLiterally(")")
|
|
3542
3680
|
c.tsw.WriteLine("")
|
|
3543
3681
|
|
|
@@ -3591,7 +3729,7 @@ func (c *GoToTSCompiler) WriteStmtSwitch(exp *ast.SwitchStmt) error {
|
|
|
3591
3729
|
return fmt.Errorf("failed to write case clause in switch statement: %w", err)
|
|
3592
3730
|
}
|
|
3593
3731
|
} else {
|
|
3594
|
-
c.tsw.
|
|
3732
|
+
c.tsw.WriteCommentLinef("unhandled statement in switch body: %T", stmt)
|
|
3595
3733
|
}
|
|
3596
3734
|
}
|
|
3597
3735
|
|
|
@@ -4547,10 +4685,11 @@ func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) error {
|
|
|
4547
4685
|
if !existsIsBlank {
|
|
4548
4686
|
c.tsw.WriteLiterally(existsName)
|
|
4549
4687
|
c.tsw.WriteLiterally(" = ")
|
|
4688
|
+
c.tsw.WriteLiterally("$.mapHas(")
|
|
4550
4689
|
if err := c.WriteValueExpr(indexExpr.X); err != nil { // Map
|
|
4551
4690
|
return err
|
|
4552
4691
|
}
|
|
4553
|
-
c.tsw.WriteLiterally("
|
|
4692
|
+
c.tsw.WriteLiterally(", ")
|
|
4554
4693
|
if err := c.WriteValueExpr(indexExpr.Index); err != nil { // Key
|
|
4555
4694
|
return err
|
|
4556
4695
|
}
|
|
@@ -4562,14 +4701,15 @@ func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) error {
|
|
|
4562
4701
|
if !valueIsBlank {
|
|
4563
4702
|
c.tsw.WriteLiterally(valueName)
|
|
4564
4703
|
c.tsw.WriteLiterally(" = ")
|
|
4704
|
+
c.tsw.WriteLiterally("$.mapGet(")
|
|
4565
4705
|
if err := c.WriteValueExpr(indexExpr.X); err != nil { // Map
|
|
4566
4706
|
return err
|
|
4567
4707
|
}
|
|
4568
|
-
c.tsw.WriteLiterally("
|
|
4708
|
+
c.tsw.WriteLiterally(", ")
|
|
4569
4709
|
if err := c.WriteValueExpr(indexExpr.Index); err != nil { // Key
|
|
4570
4710
|
return err
|
|
4571
4711
|
}
|
|
4572
|
-
c.tsw.WriteLiterally("
|
|
4712
|
+
c.tsw.WriteLiterally(", ")
|
|
4573
4713
|
// Write the zero value for the map's value type
|
|
4574
4714
|
if tv, ok := c.pkg.TypesInfo.Types[indexExpr.X]; ok {
|
|
4575
4715
|
if mapType, isMap := tv.Type.Underlying().(*types.Map); isMap {
|
|
@@ -4581,27 +4721,30 @@ func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) error {
|
|
|
4581
4721
|
} else {
|
|
4582
4722
|
c.tsw.WriteLiterally("null")
|
|
4583
4723
|
}
|
|
4724
|
+
c.tsw.WriteLiterally(")")
|
|
4584
4725
|
c.tsw.WriteLine("")
|
|
4585
4726
|
} else if existsIsBlank {
|
|
4586
4727
|
// If both are blank, still evaluate for side effects (though .has/.get are usually pure)
|
|
4587
4728
|
// We add a ; otherwise TypeScript thinks we are invoking a function.
|
|
4588
|
-
c.tsw.WriteLiterally(";(")
|
|
4729
|
+
c.tsw.WriteLiterally(";(") // Wrap in parens to make it an expression statement
|
|
4730
|
+
c.tsw.WriteLiterally("$.mapHas(")
|
|
4589
4731
|
if err := c.WriteValueExpr(indexExpr.X); err != nil { // Map
|
|
4590
4732
|
return err
|
|
4591
4733
|
}
|
|
4592
|
-
c.tsw.WriteLiterally("
|
|
4734
|
+
c.tsw.WriteLiterally(", ")
|
|
4593
4735
|
if err := c.WriteValueExpr(indexExpr.Index); err != nil { // Key
|
|
4594
4736
|
return err
|
|
4595
4737
|
}
|
|
4596
|
-
c.tsw.WriteLiterally("), ")
|
|
4738
|
+
c.tsw.WriteLiterally("), ") // Evaluate .has
|
|
4739
|
+
c.tsw.WriteLiterally("$.mapGet(")
|
|
4597
4740
|
if err := c.WriteValueExpr(indexExpr.X); err != nil { // Map
|
|
4598
4741
|
return err
|
|
4599
4742
|
}
|
|
4600
|
-
c.tsw.WriteLiterally("
|
|
4743
|
+
c.tsw.WriteLiterally(", ")
|
|
4601
4744
|
if err := c.WriteValueExpr(indexExpr.Index); err != nil { // Key
|
|
4602
4745
|
return err
|
|
4603
4746
|
}
|
|
4604
|
-
c.tsw.WriteLiterally("))") // Evaluate .get
|
|
4747
|
+
c.tsw.WriteLiterally(", null))") // Evaluate .get with null as default
|
|
4605
4748
|
c.tsw.WriteLine("")
|
|
4606
4749
|
}
|
|
4607
4750
|
|
|
@@ -5072,7 +5215,7 @@ func (c *GoToTSCompiler) WriteStmtRange(exp *ast.RangeStmt) error {
|
|
|
5072
5215
|
indexVarName = keyIdent.Name
|
|
5073
5216
|
}
|
|
5074
5217
|
}
|
|
5075
|
-
c.tsw.
|
|
5218
|
+
c.tsw.WriteLiterallyf("for (let %s = 0; %s < _runes.length; %s++) {", indexVarName, indexVarName, indexVarName)
|
|
5076
5219
|
c.tsw.Indent(1)
|
|
5077
5220
|
c.tsw.WriteLine("")
|
|
5078
5221
|
// Declare value if provided and not blank
|
|
@@ -5104,11 +5247,11 @@ func (c *GoToTSCompiler) WriteStmtRange(exp *ast.RangeStmt) error {
|
|
|
5104
5247
|
}
|
|
5105
5248
|
}
|
|
5106
5249
|
|
|
5107
|
-
c.tsw.
|
|
5250
|
+
c.tsw.WriteLiterallyf("for (let %s = 0; %s < ", indexVarName, indexVarName)
|
|
5108
5251
|
if err := c.WriteValueExpr(exp.X); err != nil { // This is N
|
|
5109
5252
|
return fmt.Errorf("failed to write range loop integer expression: %w", err)
|
|
5110
5253
|
}
|
|
5111
|
-
c.tsw.
|
|
5254
|
+
c.tsw.WriteLiterallyf("; %s++) {", indexVarName)
|
|
5112
5255
|
c.tsw.Indent(1)
|
|
5113
5256
|
c.tsw.WriteLine("")
|
|
5114
5257
|
|
|
@@ -5139,11 +5282,11 @@ func (c *GoToTSCompiler) WriteStmtRange(exp *ast.RangeStmt) error {
|
|
|
5139
5282
|
}
|
|
5140
5283
|
// If both key and value are provided, use an index loop and assign both
|
|
5141
5284
|
if exp.Key != nil && exp.Value != nil {
|
|
5142
|
-
c.tsw.
|
|
5285
|
+
c.tsw.WriteLiterallyf("for (let %s = 0; %s < $.len(", indexVarName, indexVarName)
|
|
5143
5286
|
if err := c.WriteValueExpr(exp.X); err != nil { // Write the expression for the iterable
|
|
5144
5287
|
return fmt.Errorf("failed to write range loop array/slice expression (key and value): %w", err)
|
|
5145
5288
|
}
|
|
5146
|
-
c.tsw.
|
|
5289
|
+
c.tsw.WriteLiterallyf("); %s++) {", indexVarName)
|
|
5147
5290
|
c.tsw.Indent(1)
|
|
5148
5291
|
c.tsw.WriteLine("")
|
|
5149
5292
|
// Declare value if not blank
|
|
@@ -5154,7 +5297,7 @@ func (c *GoToTSCompiler) WriteStmtRange(exp *ast.RangeStmt) error {
|
|
|
5154
5297
|
if err := c.WriteValueExpr(exp.X); err != nil {
|
|
5155
5298
|
return fmt.Errorf("failed to write range loop array/slice value expression: %w", err)
|
|
5156
5299
|
}
|
|
5157
|
-
c.tsw.
|
|
5300
|
+
c.tsw.WriteLiterallyf("![%s]", indexVarName) // Use indexVarName with not-null assert
|
|
5158
5301
|
c.tsw.WriteLine("")
|
|
5159
5302
|
}
|
|
5160
5303
|
if err := c.WriteStmt(exp.Body); err != nil {
|
|
@@ -5164,12 +5307,12 @@ func (c *GoToTSCompiler) WriteStmtRange(exp *ast.RangeStmt) error {
|
|
|
5164
5307
|
c.tsw.WriteLine("}")
|
|
5165
5308
|
return nil
|
|
5166
5309
|
} else if exp.Key != nil && exp.Value == nil { // Only key provided
|
|
5167
|
-
c.tsw.
|
|
5310
|
+
c.tsw.WriteLiterallyf("for (let %s = 0; %s < $.len(", indexVarName, indexVarName)
|
|
5168
5311
|
// Write the expression for the iterable
|
|
5169
5312
|
if err := c.WriteValueExpr(exp.X); err != nil {
|
|
5170
5313
|
return fmt.Errorf("failed to write expression for the iterable: %w", err)
|
|
5171
5314
|
}
|
|
5172
|
-
c.tsw.
|
|
5315
|
+
c.tsw.WriteLiterallyf("); %s++) {", indexVarName)
|
|
5173
5316
|
c.tsw.Indent(1)
|
|
5174
5317
|
c.tsw.WriteLine("")
|
|
5175
5318
|
if err := c.WriteStmtBlock(exp.Body, false); err != nil {
|
|
@@ -5184,11 +5327,11 @@ func (c *GoToTSCompiler) WriteStmtRange(exp *ast.RangeStmt) error {
|
|
|
5184
5327
|
} else {
|
|
5185
5328
|
// Fallback: simple index loop without declaring range variables, use _i
|
|
5186
5329
|
indexVarName := "_i"
|
|
5187
|
-
c.tsw.
|
|
5330
|
+
c.tsw.WriteLiterallyf("for (let %s = 0; %s < $.len(", indexVarName, indexVarName)
|
|
5188
5331
|
if err := c.WriteValueExpr(exp.X); err != nil {
|
|
5189
5332
|
return fmt.Errorf("failed to write range loop array/slice length expression (fallback): %w", err)
|
|
5190
5333
|
}
|
|
5191
|
-
c.tsw.
|
|
5334
|
+
c.tsw.WriteLiterallyf("); %s++) {", indexVarName)
|
|
5192
5335
|
c.tsw.Indent(1)
|
|
5193
5336
|
c.tsw.WriteLine("")
|
|
5194
5337
|
if err := c.WriteStmtBlock(exp.Body, false); err != nil {
|
|
@@ -5249,6 +5392,15 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5249
5392
|
interfaceExpr := typeAssertExpr.X
|
|
5250
5393
|
assertedType := typeAssertExpr.Type
|
|
5251
5394
|
|
|
5395
|
+
// Unwrap parenthesized expressions to handle cases like r.((<-chan T))
|
|
5396
|
+
for {
|
|
5397
|
+
if parenExpr, ok := assertedType.(*ast.ParenExpr); ok {
|
|
5398
|
+
assertedType = parenExpr.X
|
|
5399
|
+
} else {
|
|
5400
|
+
break
|
|
5401
|
+
}
|
|
5402
|
+
}
|
|
5403
|
+
|
|
5252
5404
|
// Ensure LHS has exactly two expressions (value and ok)
|
|
5253
5405
|
if len(lhs) != 2 {
|
|
5254
5406
|
return fmt.Errorf("type assertion assignment requires exactly 2 variables on LHS, got %d", len(lhs))
|
|
@@ -5259,32 +5411,93 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5259
5411
|
okIsBlank := false
|
|
5260
5412
|
var valueName string
|
|
5261
5413
|
var okName string
|
|
5414
|
+
var valueIdent *ast.Ident
|
|
5415
|
+
var okIdent *ast.Ident
|
|
5262
5416
|
|
|
5263
|
-
if
|
|
5264
|
-
|
|
5417
|
+
if valId, ok := lhs[0].(*ast.Ident); ok {
|
|
5418
|
+
valueIdent = valId
|
|
5419
|
+
if valId.Name == "_" {
|
|
5265
5420
|
valueIsBlank = true
|
|
5266
5421
|
} else {
|
|
5267
|
-
valueName =
|
|
5422
|
+
valueName = valId.Name
|
|
5268
5423
|
}
|
|
5269
5424
|
} else {
|
|
5270
5425
|
return fmt.Errorf("unhandled LHS expression type for value in type assertion: %T", lhs[0])
|
|
5271
5426
|
}
|
|
5272
5427
|
|
|
5273
|
-
if
|
|
5274
|
-
|
|
5428
|
+
if okId, ok := lhs[1].(*ast.Ident); ok {
|
|
5429
|
+
okIdent = okId
|
|
5430
|
+
if okId.Name == "_" {
|
|
5275
5431
|
okIsBlank = true
|
|
5276
5432
|
} else {
|
|
5277
|
-
okName =
|
|
5433
|
+
okName = okId.Name
|
|
5278
5434
|
}
|
|
5279
5435
|
} else {
|
|
5280
5436
|
return fmt.Errorf("unhandled LHS expression type for ok in type assertion: %T", lhs[1])
|
|
5281
5437
|
}
|
|
5282
5438
|
|
|
5283
|
-
//
|
|
5439
|
+
// For token.DEFINE (:=), we need to check if any of the variables are already declared
|
|
5440
|
+
// In Go, := can be used for redeclaration if at least one variable is new
|
|
5441
|
+
writeEndParen := false
|
|
5284
5442
|
if tok == token.DEFINE {
|
|
5285
|
-
|
|
5443
|
+
// Identify which variables are new vs existing
|
|
5444
|
+
valueIsNew := true
|
|
5445
|
+
okIsNew := true
|
|
5446
|
+
anyNewVars := false
|
|
5447
|
+
allNewVars := true
|
|
5448
|
+
|
|
5449
|
+
// Check if variables are already in scope
|
|
5450
|
+
if !valueIsBlank {
|
|
5451
|
+
if obj := c.pkg.TypesInfo.Uses[valueIdent]; obj != nil {
|
|
5452
|
+
// If it's in Uses, it's referenced elsewhere, so it exists
|
|
5453
|
+
valueIsNew = false
|
|
5454
|
+
allNewVars = false
|
|
5455
|
+
}
|
|
5456
|
+
if valueIsNew {
|
|
5457
|
+
anyNewVars = true
|
|
5458
|
+
}
|
|
5459
|
+
}
|
|
5460
|
+
|
|
5461
|
+
if !okIsBlank {
|
|
5462
|
+
if obj := c.pkg.TypesInfo.Uses[okIdent]; obj != nil {
|
|
5463
|
+
// If it's in Uses, it's referenced elsewhere, so it exists
|
|
5464
|
+
okIsNew = false
|
|
5465
|
+
allNewVars = false
|
|
5466
|
+
}
|
|
5467
|
+
if okIsNew {
|
|
5468
|
+
anyNewVars = true
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
|
|
5472
|
+
if allNewVars && anyNewVars {
|
|
5473
|
+
c.tsw.WriteLiterally("let ")
|
|
5474
|
+
} else if anyNewVars {
|
|
5475
|
+
// If only some variables are new, declare them separately
|
|
5476
|
+
if !valueIsBlank && valueIsNew {
|
|
5477
|
+
c.tsw.WriteLiterally("let ")
|
|
5478
|
+
c.tsw.WriteLiterally(valueName)
|
|
5479
|
+
// Add type annotation if possible
|
|
5480
|
+
if tv, ok := c.pkg.TypesInfo.Types[assertedType]; ok {
|
|
5481
|
+
c.tsw.WriteLiterally(": ")
|
|
5482
|
+
c.WriteGoType(tv.Type)
|
|
5483
|
+
}
|
|
5484
|
+
c.tsw.WriteLine("")
|
|
5485
|
+
}
|
|
5486
|
+
if !okIsBlank && okIsNew {
|
|
5487
|
+
c.tsw.WriteLiterally("let ")
|
|
5488
|
+
c.tsw.WriteLiterally(okName)
|
|
5489
|
+
c.tsw.WriteLiterally(": boolean") // ok is always boolean
|
|
5490
|
+
c.tsw.WriteLine("")
|
|
5491
|
+
}
|
|
5492
|
+
// Use parenthesized destructuring assignment for existing variables
|
|
5493
|
+
c.tsw.WriteLiterally(";(")
|
|
5494
|
+
writeEndParen = true
|
|
5495
|
+
} else {
|
|
5496
|
+
// All variables exist, use parenthesized destructuring assignment
|
|
5497
|
+
c.tsw.WriteLiterally(";(")
|
|
5498
|
+
writeEndParen = true
|
|
5499
|
+
}
|
|
5286
5500
|
} else {
|
|
5287
|
-
// We must wrap in parenthesis.
|
|
5288
5501
|
c.tsw.WriteLiterally("(")
|
|
5289
5502
|
}
|
|
5290
5503
|
|
|
@@ -5319,9 +5532,9 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5319
5532
|
c.tsw.WriteLiterally("keyType: ")
|
|
5320
5533
|
if ident, ok := typeExpr.Key.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
5321
5534
|
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
5322
|
-
c.tsw.
|
|
5535
|
+
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
5323
5536
|
} else {
|
|
5324
|
-
c.tsw.
|
|
5537
|
+
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
5325
5538
|
}
|
|
5326
5539
|
} else {
|
|
5327
5540
|
c.writeTypeDescription(typeExpr.Key)
|
|
@@ -5333,9 +5546,9 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5333
5546
|
c.tsw.WriteLiterally("elemType: ")
|
|
5334
5547
|
if ident, ok := typeExpr.Value.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
5335
5548
|
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
5336
|
-
c.tsw.
|
|
5549
|
+
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
5337
5550
|
} else {
|
|
5338
|
-
c.tsw.
|
|
5551
|
+
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
5339
5552
|
}
|
|
5340
5553
|
} else {
|
|
5341
5554
|
c.writeTypeDescription(typeExpr.Value)
|
|
@@ -5351,15 +5564,15 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5351
5564
|
|
|
5352
5565
|
// Create a type descriptor object
|
|
5353
5566
|
c.tsw.WriteLiterally("{")
|
|
5354
|
-
c.tsw.
|
|
5567
|
+
c.tsw.WriteLiterallyf("kind: %s, ", typeKind)
|
|
5355
5568
|
|
|
5356
5569
|
// Add element type
|
|
5357
5570
|
c.tsw.WriteLiterally("elemType: ")
|
|
5358
5571
|
if ident, ok := typeExpr.Elt.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
5359
5572
|
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
5360
|
-
c.tsw.
|
|
5573
|
+
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
5361
5574
|
} else {
|
|
5362
|
-
c.tsw.
|
|
5575
|
+
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
5363
5576
|
}
|
|
5364
5577
|
} else {
|
|
5365
5578
|
c.writeTypeDescription(typeExpr.Elt)
|
|
@@ -5374,21 +5587,30 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5374
5587
|
// Get the type name if available
|
|
5375
5588
|
typeName := c.getTypeNameString(assertedType)
|
|
5376
5589
|
if typeName != "unknown" {
|
|
5377
|
-
c.tsw.
|
|
5590
|
+
c.tsw.WriteLiterallyf(", name: '%s'", typeName)
|
|
5378
5591
|
}
|
|
5379
5592
|
|
|
5380
5593
|
if typeExpr.Fields != nil && typeExpr.Fields.List != nil {
|
|
5381
|
-
|
|
5594
|
+
// Add fields property to provide type information
|
|
5595
|
+
c.tsw.WriteLiterally(", fields: {")
|
|
5382
5596
|
|
|
5383
|
-
|
|
5597
|
+
hasFields := false
|
|
5384
5598
|
for _, field := range typeExpr.Fields.List {
|
|
5385
|
-
|
|
5386
|
-
|
|
5599
|
+
if len(field.Names) > 0 {
|
|
5600
|
+
for _, name := range field.Names {
|
|
5601
|
+
if hasFields {
|
|
5602
|
+
c.tsw.WriteLiterally(", ")
|
|
5603
|
+
}
|
|
5604
|
+
c.tsw.WriteLiterally(fmt.Sprintf("'%s': ", name.Name))
|
|
5605
|
+
c.writeTypeDescription(field.Type)
|
|
5606
|
+
hasFields = true
|
|
5607
|
+
}
|
|
5387
5608
|
}
|
|
5388
5609
|
}
|
|
5389
5610
|
|
|
5390
|
-
c.tsw.WriteLiterally(
|
|
5391
|
-
|
|
5611
|
+
c.tsw.WriteLiterally("}")
|
|
5612
|
+
} else {
|
|
5613
|
+
c.tsw.WriteLiterally(", fields: {}")
|
|
5392
5614
|
}
|
|
5393
5615
|
|
|
5394
5616
|
// Add empty methods set to satisfy StructTypeInfo interface
|
|
@@ -5402,7 +5624,7 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5402
5624
|
// Get the type name if available
|
|
5403
5625
|
typeName := c.getTypeNameString(assertedType)
|
|
5404
5626
|
if typeName != "unknown" {
|
|
5405
|
-
c.tsw.
|
|
5627
|
+
c.tsw.WriteLiterallyf(", name: '%s'", typeName)
|
|
5406
5628
|
}
|
|
5407
5629
|
|
|
5408
5630
|
// Add methods if available
|
|
@@ -5425,9 +5647,12 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5425
5647
|
c.tsw.WriteLiterally("{")
|
|
5426
5648
|
c.tsw.WriteLiterally("kind: $.TypeKind.Pointer")
|
|
5427
5649
|
|
|
5428
|
-
// Add element type if it's a named type
|
|
5429
|
-
if
|
|
5430
|
-
c.tsw.WriteLiterally(
|
|
5650
|
+
// Add element type if it's a struct type or named type
|
|
5651
|
+
if structType, ok := typeExpr.X.(*ast.StructType); ok {
|
|
5652
|
+
c.tsw.WriteLiterally(", elemType: ")
|
|
5653
|
+
c.writeTypeDescription(structType)
|
|
5654
|
+
} else if ident, ok := typeExpr.X.(*ast.Ident); ok {
|
|
5655
|
+
c.tsw.WriteLiterallyf(", elemType: '%s'", ident.Name)
|
|
5431
5656
|
}
|
|
5432
5657
|
|
|
5433
5658
|
c.tsw.WriteLiterally("}")
|
|
@@ -5439,19 +5664,64 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5439
5664
|
c.tsw.WriteLiterally(", elemType: ")
|
|
5440
5665
|
if ident, ok := typeExpr.Value.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
5441
5666
|
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
5442
|
-
c.tsw.
|
|
5667
|
+
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
5443
5668
|
} else {
|
|
5444
|
-
c.tsw.
|
|
5669
|
+
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
5445
5670
|
}
|
|
5446
5671
|
} else {
|
|
5447
5672
|
c.writeTypeDescription(typeExpr.Value)
|
|
5448
5673
|
}
|
|
5449
5674
|
|
|
5675
|
+
c.tsw.WriteLiterally(", direction: ")
|
|
5676
|
+
switch typeExpr.Dir {
|
|
5677
|
+
case ast.SEND:
|
|
5678
|
+
c.tsw.WriteLiterally("'send'")
|
|
5679
|
+
case ast.RECV:
|
|
5680
|
+
c.tsw.WriteLiterally("'receive'")
|
|
5681
|
+
case ast.SEND | ast.RECV: // bidirectional
|
|
5682
|
+
c.tsw.WriteLiterally("'both'")
|
|
5683
|
+
default:
|
|
5684
|
+
// This should not happen, but just in case
|
|
5685
|
+
c.tsw.WriteLiterally("'both'")
|
|
5686
|
+
}
|
|
5687
|
+
|
|
5450
5688
|
c.tsw.WriteLiterally("}")
|
|
5451
5689
|
case *ast.FuncType:
|
|
5452
|
-
// For function types, create a type descriptor object
|
|
5690
|
+
// For function types, create a type descriptor object with params and results
|
|
5453
5691
|
c.tsw.WriteLiterally("{")
|
|
5454
5692
|
c.tsw.WriteLiterally("kind: $.TypeKind.Function")
|
|
5693
|
+
|
|
5694
|
+
// Add name if this is a named function type
|
|
5695
|
+
if namedType := c.pkg.TypesInfo.TypeOf(typeExpr); namedType != nil {
|
|
5696
|
+
if named, ok := namedType.(*types.Named); ok {
|
|
5697
|
+
c.tsw.WriteLiterallyf(", name: '%s'", named.Obj().Name())
|
|
5698
|
+
}
|
|
5699
|
+
}
|
|
5700
|
+
|
|
5701
|
+
// Add params if present
|
|
5702
|
+
if typeExpr.Params != nil && len(typeExpr.Params.List) > 0 {
|
|
5703
|
+
c.tsw.WriteLiterally(", params: [")
|
|
5704
|
+
for i, param := range typeExpr.Params.List {
|
|
5705
|
+
if i > 0 {
|
|
5706
|
+
c.tsw.WriteLiterally(", ")
|
|
5707
|
+
}
|
|
5708
|
+
c.writeTypeDescription(param.Type)
|
|
5709
|
+
}
|
|
5710
|
+
c.tsw.WriteLiterally("]")
|
|
5711
|
+
}
|
|
5712
|
+
|
|
5713
|
+
// Add results if present
|
|
5714
|
+
if typeExpr.Results != nil && len(typeExpr.Results.List) > 0 {
|
|
5715
|
+
c.tsw.WriteLiterally(", results: [")
|
|
5716
|
+
for i, result := range typeExpr.Results.List {
|
|
5717
|
+
if i > 0 {
|
|
5718
|
+
c.tsw.WriteLiterally(", ")
|
|
5719
|
+
}
|
|
5720
|
+
c.writeTypeDescription(result.Type)
|
|
5721
|
+
}
|
|
5722
|
+
c.tsw.WriteLiterally("]")
|
|
5723
|
+
}
|
|
5724
|
+
|
|
5455
5725
|
c.tsw.WriteLiterally("}")
|
|
5456
5726
|
case *ast.Ident:
|
|
5457
5727
|
if isPrimitiveType(typeExpr.Name) {
|
|
@@ -5460,31 +5730,102 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5460
5730
|
|
|
5461
5731
|
// Use TypeScript equivalent if available
|
|
5462
5732
|
if tsType, ok := GoBuiltinToTypescript(typeExpr.Name); ok {
|
|
5463
|
-
c.tsw.
|
|
5733
|
+
c.tsw.WriteLiterallyf("name: '%s'", tsType) // TODO: use %q?
|
|
5464
5734
|
} else {
|
|
5465
|
-
c.tsw.
|
|
5735
|
+
c.tsw.WriteLiterallyf("name: '%s'", typeExpr.Name)
|
|
5466
5736
|
}
|
|
5467
5737
|
|
|
5468
5738
|
c.tsw.WriteLiterally("}")
|
|
5469
5739
|
} else {
|
|
5470
|
-
|
|
5740
|
+
// Check if this is a named function type
|
|
5741
|
+
isFunctionType := false
|
|
5742
|
+
if namedType := c.pkg.TypesInfo.TypeOf(typeExpr); namedType != nil {
|
|
5743
|
+
if named, ok := namedType.(*types.Named); ok {
|
|
5744
|
+
if _, ok := named.Underlying().(*types.Signature); ok {
|
|
5745
|
+
// This is a named function type, generate a FunctionTypeInfo
|
|
5746
|
+
isFunctionType = true
|
|
5747
|
+
c.tsw.WriteLiterally("{")
|
|
5748
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Function")
|
|
5749
|
+
c.tsw.WriteLiterallyf(", name: '%s'", typeExpr.Name)
|
|
5750
|
+
|
|
5751
|
+
// Get the underlying signature
|
|
5752
|
+
signature := named.Underlying().(*types.Signature)
|
|
5753
|
+
|
|
5754
|
+
// Add params if present
|
|
5755
|
+
params := signature.Params()
|
|
5756
|
+
if params != nil && params.Len() > 0 {
|
|
5757
|
+
c.tsw.WriteLiterally(", params: [")
|
|
5758
|
+
for i := 0; i < params.Len(); i++ {
|
|
5759
|
+
if i > 0 {
|
|
5760
|
+
c.tsw.WriteLiterally(", ")
|
|
5761
|
+
}
|
|
5762
|
+
// Use basic type info for parameters
|
|
5763
|
+
param := params.At(i)
|
|
5764
|
+
c.tsw.WriteLiterally("{")
|
|
5765
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
|
|
5766
|
+
|
|
5767
|
+
typeName := param.Type().String()
|
|
5768
|
+
if tsType, ok := GoBuiltinToTypescript(typeName); ok {
|
|
5769
|
+
c.tsw.WriteLiterallyf("name: '%s'", tsType)
|
|
5770
|
+
} else {
|
|
5771
|
+
c.tsw.WriteLiterallyf("name: '%s'", typeName)
|
|
5772
|
+
}
|
|
5773
|
+
|
|
5774
|
+
c.tsw.WriteLiterally("}")
|
|
5775
|
+
}
|
|
5776
|
+
c.tsw.WriteLiterally("]")
|
|
5777
|
+
}
|
|
5778
|
+
|
|
5779
|
+
// Add results if present
|
|
5780
|
+
results := signature.Results()
|
|
5781
|
+
if results != nil && results.Len() > 0 {
|
|
5782
|
+
c.tsw.WriteLiterally(", results: [")
|
|
5783
|
+
for i := 0; i < results.Len(); i++ {
|
|
5784
|
+
if i > 0 {
|
|
5785
|
+
c.tsw.WriteLiterally(", ")
|
|
5786
|
+
}
|
|
5787
|
+
result := results.At(i)
|
|
5788
|
+
c.tsw.WriteLiterally("{")
|
|
5789
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
|
|
5790
|
+
|
|
5791
|
+
typeName := result.Type().String()
|
|
5792
|
+
if tsType, ok := GoBuiltinToTypescript(typeName); ok {
|
|
5793
|
+
c.tsw.WriteLiterallyf("name: '%s'", tsType)
|
|
5794
|
+
} else {
|
|
5795
|
+
c.tsw.WriteLiterallyf("name: '%s'", typeName)
|
|
5796
|
+
}
|
|
5797
|
+
|
|
5798
|
+
c.tsw.WriteLiterally("}")
|
|
5799
|
+
}
|
|
5800
|
+
c.tsw.WriteLiterally("]")
|
|
5801
|
+
}
|
|
5802
|
+
|
|
5803
|
+
c.tsw.WriteLiterally("}")
|
|
5804
|
+
}
|
|
5805
|
+
}
|
|
5806
|
+
}
|
|
5807
|
+
|
|
5808
|
+
// Default case for non-function named types
|
|
5809
|
+
if !isFunctionType {
|
|
5810
|
+
c.tsw.WriteLiterallyf("'%s'", typeExpr.Name)
|
|
5811
|
+
}
|
|
5471
5812
|
}
|
|
5472
5813
|
case *ast.SelectorExpr:
|
|
5473
5814
|
// For imported types like pkg.Type
|
|
5474
5815
|
if ident, ok := typeExpr.X.(*ast.Ident); ok {
|
|
5475
|
-
c.tsw.
|
|
5816
|
+
c.tsw.WriteLiterallyf("'%s.%s'", ident.Name, typeExpr.Sel.Name)
|
|
5476
5817
|
} else {
|
|
5477
|
-
c.tsw.
|
|
5818
|
+
c.tsw.WriteLiterallyf("'%s'", c.getTypeNameString(assertedType))
|
|
5478
5819
|
}
|
|
5479
5820
|
default:
|
|
5480
5821
|
// For other types, use the string name as before
|
|
5481
5822
|
typeName := c.getTypeNameString(assertedType)
|
|
5482
|
-
c.tsw.
|
|
5823
|
+
c.tsw.WriteLiterallyf("'%s'", typeName)
|
|
5483
5824
|
}
|
|
5484
5825
|
|
|
5485
5826
|
c.tsw.WriteLiterally(")")
|
|
5486
5827
|
|
|
5487
|
-
if tok != token.DEFINE {
|
|
5828
|
+
if tok != token.DEFINE || writeEndParen {
|
|
5488
5829
|
c.tsw.WriteLiterally(")")
|
|
5489
5830
|
}
|
|
5490
5831
|
|
|
@@ -5506,22 +5847,22 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5506
5847
|
if tsType, ok := GoBuiltinToTypescript(t.Name); ok {
|
|
5507
5848
|
c.tsw.WriteLiterally("{")
|
|
5508
5849
|
c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
|
|
5509
|
-
c.tsw.
|
|
5850
|
+
c.tsw.WriteLiterallyf("name: '%s'", tsType)
|
|
5510
5851
|
c.tsw.WriteLiterally("}")
|
|
5511
5852
|
} else {
|
|
5512
5853
|
// Fallback for other primitive types
|
|
5513
5854
|
c.tsw.WriteLiterally("{")
|
|
5514
5855
|
c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
|
|
5515
|
-
c.tsw.
|
|
5856
|
+
c.tsw.WriteLiterallyf("name: '%s'", t.Name)
|
|
5516
5857
|
c.tsw.WriteLiterally("}")
|
|
5517
5858
|
}
|
|
5518
5859
|
} else {
|
|
5519
5860
|
// For named types, just use the name string
|
|
5520
|
-
c.tsw.
|
|
5861
|
+
c.tsw.WriteLiterallyf("'%s'", t.Name)
|
|
5521
5862
|
}
|
|
5522
5863
|
case *ast.SelectorExpr:
|
|
5523
5864
|
if ident, ok := t.X.(*ast.Ident); ok {
|
|
5524
|
-
c.tsw.
|
|
5865
|
+
c.tsw.WriteLiterallyf("'%s.%s'", ident.Name, t.Sel.Name)
|
|
5525
5866
|
}
|
|
5526
5867
|
case *ast.ArrayType:
|
|
5527
5868
|
typeKind := "$.TypeKind.Slice"
|
|
@@ -5530,7 +5871,7 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5530
5871
|
}
|
|
5531
5872
|
|
|
5532
5873
|
c.tsw.WriteLiterally("{")
|
|
5533
|
-
c.tsw.
|
|
5874
|
+
c.tsw.WriteLiterallyf("kind: %s, ", typeKind)
|
|
5534
5875
|
c.tsw.WriteLiterally("elemType: ")
|
|
5535
5876
|
c.writeTypeDescription(t.Elt)
|
|
5536
5877
|
c.tsw.WriteLiterally("}")
|
|
@@ -5540,20 +5881,7 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5540
5881
|
|
|
5541
5882
|
// Add field names and types to the struct type info
|
|
5542
5883
|
if t.Fields != nil && t.Fields.List != nil {
|
|
5543
|
-
c.tsw.WriteLiterally("fields:
|
|
5544
|
-
|
|
5545
|
-
fields := []string{}
|
|
5546
|
-
for _, field := range t.Fields.List {
|
|
5547
|
-
for _, name := range field.Names {
|
|
5548
|
-
fields = append(fields, fmt.Sprintf("'%s'", name.Name))
|
|
5549
|
-
}
|
|
5550
|
-
}
|
|
5551
|
-
|
|
5552
|
-
c.tsw.WriteLiterally(strings.Join(fields, ", "))
|
|
5553
|
-
c.tsw.WriteLiterally("]), ")
|
|
5554
|
-
|
|
5555
|
-
// Add fieldTypes property to provide type information
|
|
5556
|
-
c.tsw.WriteLiterally("fieldTypes: {")
|
|
5884
|
+
c.tsw.WriteLiterally("fields: {")
|
|
5557
5885
|
|
|
5558
5886
|
hasFields := false
|
|
5559
5887
|
for _, field := range t.Fields.List {
|
|
@@ -5562,7 +5890,7 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5562
5890
|
if hasFields {
|
|
5563
5891
|
c.tsw.WriteLiterally(", ")
|
|
5564
5892
|
}
|
|
5565
|
-
c.tsw.
|
|
5893
|
+
c.tsw.WriteLiterallyf("'%s': ", name.Name)
|
|
5566
5894
|
c.writeTypeDescription(field.Type)
|
|
5567
5895
|
hasFields = true
|
|
5568
5896
|
}
|
|
@@ -5571,7 +5899,7 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5571
5899
|
|
|
5572
5900
|
c.tsw.WriteLiterally("}, ")
|
|
5573
5901
|
} else {
|
|
5574
|
-
c.tsw.WriteLiterally("fields:
|
|
5902
|
+
c.tsw.WriteLiterally("fields: {}, ")
|
|
5575
5903
|
}
|
|
5576
5904
|
|
|
5577
5905
|
c.tsw.WriteLiterally("methods: new Set()")
|
|
@@ -5591,10 +5919,79 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5591
5919
|
c.tsw.WriteLiterally("kind: $.TypeKind.Pointer, ")
|
|
5592
5920
|
c.tsw.WriteLiterally("elemType: ")
|
|
5593
5921
|
c.writeTypeDescription(t.X)
|
|
5922
|
+
c.tsw.WriteLiterally("}")
|
|
5923
|
+
case *ast.FuncType:
|
|
5924
|
+
// For function types, create a type descriptor object with params and results
|
|
5925
|
+
c.tsw.WriteLiterally("{")
|
|
5926
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Function")
|
|
5927
|
+
|
|
5928
|
+
// Add name if this is a named function type
|
|
5929
|
+
if namedType := c.pkg.TypesInfo.TypeOf(typeExpr); namedType != nil {
|
|
5930
|
+
if named, ok := namedType.(*types.Named); ok {
|
|
5931
|
+
c.tsw.WriteLiterallyf(", name: '%s'", named.Obj().Name())
|
|
5932
|
+
}
|
|
5933
|
+
}
|
|
5934
|
+
|
|
5935
|
+
// Add params if present
|
|
5936
|
+
if t.Params != nil && len(t.Params.List) > 0 {
|
|
5937
|
+
c.tsw.WriteLiterally(", params: [")
|
|
5938
|
+
for i, param := range t.Params.List {
|
|
5939
|
+
if i > 0 {
|
|
5940
|
+
c.tsw.WriteLiterally(", ")
|
|
5941
|
+
}
|
|
5942
|
+
c.writeTypeDescription(param.Type)
|
|
5943
|
+
}
|
|
5944
|
+
c.tsw.WriteLiterally("]")
|
|
5945
|
+
}
|
|
5946
|
+
|
|
5947
|
+
// Add results if present
|
|
5948
|
+
if t.Results != nil && len(t.Results.List) > 0 {
|
|
5949
|
+
c.tsw.WriteLiterally(", results: [")
|
|
5950
|
+
for i, result := range t.Results.List {
|
|
5951
|
+
if i > 0 {
|
|
5952
|
+
c.tsw.WriteLiterally(", ")
|
|
5953
|
+
}
|
|
5954
|
+
c.writeTypeDescription(result.Type)
|
|
5955
|
+
}
|
|
5956
|
+
c.tsw.WriteLiterally("]")
|
|
5957
|
+
}
|
|
5958
|
+
|
|
5959
|
+
c.tsw.WriteLiterally("}")
|
|
5960
|
+
return
|
|
5961
|
+
case *ast.ChanType:
|
|
5962
|
+
c.tsw.WriteLiterally("{")
|
|
5963
|
+
c.tsw.WriteLiterally("kind: $.TypeKind.Channel, ")
|
|
5964
|
+
c.tsw.WriteLiterally("elemType: ")
|
|
5965
|
+
|
|
5966
|
+
// Add element type
|
|
5967
|
+
if ident, ok := t.Value.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
5968
|
+
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
5969
|
+
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
5970
|
+
} else {
|
|
5971
|
+
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
5972
|
+
}
|
|
5973
|
+
} else {
|
|
5974
|
+
c.writeTypeDescription(t.Value)
|
|
5975
|
+
}
|
|
5976
|
+
|
|
5977
|
+
// Add direction
|
|
5978
|
+
c.tsw.WriteLiterally(", direction: ")
|
|
5979
|
+
switch t.Dir {
|
|
5980
|
+
case ast.SEND:
|
|
5981
|
+
c.tsw.WriteLiterally("'send'")
|
|
5982
|
+
case ast.RECV:
|
|
5983
|
+
c.tsw.WriteLiterally("'receive'")
|
|
5984
|
+
case ast.SEND | ast.RECV: // bidirectional
|
|
5985
|
+
c.tsw.WriteLiterally("'both'")
|
|
5986
|
+
default:
|
|
5987
|
+
// This should not happen, but just in case
|
|
5988
|
+
c.tsw.WriteLiterally("'both'")
|
|
5989
|
+
}
|
|
5990
|
+
|
|
5594
5991
|
c.tsw.WriteLiterally("}")
|
|
5595
5992
|
default:
|
|
5596
5993
|
// For other types, use the string representation
|
|
5597
|
-
c.tsw.
|
|
5994
|
+
c.tsw.WriteLiterallyf("'%s'", c.getTypeNameString(typeExpr))
|
|
5598
5995
|
}
|
|
5599
5996
|
}
|
|
5600
5997
|
|