goscript 0.0.17 → 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 +467 -75
- 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")
|
|
@@ -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("(")
|
|
@@ -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 {
|
|
@@ -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)
|
|
@@ -3198,6 +3332,10 @@ 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
3340
|
c.tsw.WriteCommentLinef("unhandled spec in DeclStmt: %T", spec)
|
|
3203
3341
|
}
|
|
@@ -5254,6 +5392,15 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5254
5392
|
interfaceExpr := typeAssertExpr.X
|
|
5255
5393
|
assertedType := typeAssertExpr.Type
|
|
5256
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
|
+
|
|
5257
5404
|
// Ensure LHS has exactly two expressions (value and ok)
|
|
5258
5405
|
if len(lhs) != 2 {
|
|
5259
5406
|
return fmt.Errorf("type assertion assignment requires exactly 2 variables on LHS, got %d", len(lhs))
|
|
@@ -5264,32 +5411,93 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5264
5411
|
okIsBlank := false
|
|
5265
5412
|
var valueName string
|
|
5266
5413
|
var okName string
|
|
5414
|
+
var valueIdent *ast.Ident
|
|
5415
|
+
var okIdent *ast.Ident
|
|
5267
5416
|
|
|
5268
|
-
if
|
|
5269
|
-
|
|
5417
|
+
if valId, ok := lhs[0].(*ast.Ident); ok {
|
|
5418
|
+
valueIdent = valId
|
|
5419
|
+
if valId.Name == "_" {
|
|
5270
5420
|
valueIsBlank = true
|
|
5271
5421
|
} else {
|
|
5272
|
-
valueName =
|
|
5422
|
+
valueName = valId.Name
|
|
5273
5423
|
}
|
|
5274
5424
|
} else {
|
|
5275
5425
|
return fmt.Errorf("unhandled LHS expression type for value in type assertion: %T", lhs[0])
|
|
5276
5426
|
}
|
|
5277
5427
|
|
|
5278
|
-
if
|
|
5279
|
-
|
|
5428
|
+
if okId, ok := lhs[1].(*ast.Ident); ok {
|
|
5429
|
+
okIdent = okId
|
|
5430
|
+
if okId.Name == "_" {
|
|
5280
5431
|
okIsBlank = true
|
|
5281
5432
|
} else {
|
|
5282
|
-
okName =
|
|
5433
|
+
okName = okId.Name
|
|
5283
5434
|
}
|
|
5284
5435
|
} else {
|
|
5285
5436
|
return fmt.Errorf("unhandled LHS expression type for ok in type assertion: %T", lhs[1])
|
|
5286
5437
|
}
|
|
5287
5438
|
|
|
5288
|
-
//
|
|
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
|
|
5289
5442
|
if tok == token.DEFINE {
|
|
5290
|
-
|
|
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
|
+
}
|
|
5291
5500
|
} else {
|
|
5292
|
-
// We must wrap in parenthesis.
|
|
5293
5501
|
c.tsw.WriteLiterally("(")
|
|
5294
5502
|
}
|
|
5295
5503
|
|
|
@@ -5383,17 +5591,26 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5383
5591
|
}
|
|
5384
5592
|
|
|
5385
5593
|
if typeExpr.Fields != nil && typeExpr.Fields.List != nil {
|
|
5386
|
-
|
|
5594
|
+
// Add fields property to provide type information
|
|
5595
|
+
c.tsw.WriteLiterally(", fields: {")
|
|
5387
5596
|
|
|
5388
|
-
|
|
5597
|
+
hasFields := false
|
|
5389
5598
|
for _, field := range typeExpr.Fields.List {
|
|
5390
|
-
|
|
5391
|
-
|
|
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
|
+
}
|
|
5392
5608
|
}
|
|
5393
5609
|
}
|
|
5394
5610
|
|
|
5395
|
-
c.tsw.WriteLiterally(
|
|
5396
|
-
|
|
5611
|
+
c.tsw.WriteLiterally("}")
|
|
5612
|
+
} else {
|
|
5613
|
+
c.tsw.WriteLiterally(", fields: {}")
|
|
5397
5614
|
}
|
|
5398
5615
|
|
|
5399
5616
|
// Add empty methods set to satisfy StructTypeInfo interface
|
|
@@ -5430,8 +5647,11 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5430
5647
|
c.tsw.WriteLiterally("{")
|
|
5431
5648
|
c.tsw.WriteLiterally("kind: $.TypeKind.Pointer")
|
|
5432
5649
|
|
|
5433
|
-
// Add element type if it's a named type
|
|
5434
|
-
if
|
|
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 {
|
|
5435
5655
|
c.tsw.WriteLiterallyf(", elemType: '%s'", ident.Name)
|
|
5436
5656
|
}
|
|
5437
5657
|
|
|
@@ -5452,11 +5672,56 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5452
5672
|
c.writeTypeDescription(typeExpr.Value)
|
|
5453
5673
|
}
|
|
5454
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
|
+
|
|
5455
5688
|
c.tsw.WriteLiterally("}")
|
|
5456
5689
|
case *ast.FuncType:
|
|
5457
|
-
// For function types, create a type descriptor object
|
|
5690
|
+
// For function types, create a type descriptor object with params and results
|
|
5458
5691
|
c.tsw.WriteLiterally("{")
|
|
5459
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
|
+
|
|
5460
5725
|
c.tsw.WriteLiterally("}")
|
|
5461
5726
|
case *ast.Ident:
|
|
5462
5727
|
if isPrimitiveType(typeExpr.Name) {
|
|
@@ -5472,7 +5737,78 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5472
5737
|
|
|
5473
5738
|
c.tsw.WriteLiterally("}")
|
|
5474
5739
|
} else {
|
|
5475
|
-
|
|
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
|
+
}
|
|
5476
5812
|
}
|
|
5477
5813
|
case *ast.SelectorExpr:
|
|
5478
5814
|
// For imported types like pkg.Type
|
|
@@ -5489,7 +5825,7 @@ func (c *GoToTSCompiler) writeTypeAssertion(lhs []ast.Expr, typeAssertExpr *ast.
|
|
|
5489
5825
|
|
|
5490
5826
|
c.tsw.WriteLiterally(")")
|
|
5491
5827
|
|
|
5492
|
-
if tok != token.DEFINE {
|
|
5828
|
+
if tok != token.DEFINE || writeEndParen {
|
|
5493
5829
|
c.tsw.WriteLiterally(")")
|
|
5494
5830
|
}
|
|
5495
5831
|
|
|
@@ -5545,20 +5881,7 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5545
5881
|
|
|
5546
5882
|
// Add field names and types to the struct type info
|
|
5547
5883
|
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: {")
|
|
5884
|
+
c.tsw.WriteLiterally("fields: {")
|
|
5562
5885
|
|
|
5563
5886
|
hasFields := false
|
|
5564
5887
|
for _, field := range t.Fields.List {
|
|
@@ -5576,7 +5899,7 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5576
5899
|
|
|
5577
5900
|
c.tsw.WriteLiterally("}, ")
|
|
5578
5901
|
} else {
|
|
5579
|
-
c.tsw.WriteLiterally("fields:
|
|
5902
|
+
c.tsw.WriteLiterally("fields: {}, ")
|
|
5580
5903
|
}
|
|
5581
5904
|
|
|
5582
5905
|
c.tsw.WriteLiterally("methods: new Set()")
|
|
@@ -5596,6 +5919,75 @@ func (c *GoToTSCompiler) writeTypeDescription(typeExpr ast.Expr) {
|
|
|
5596
5919
|
c.tsw.WriteLiterally("kind: $.TypeKind.Pointer, ")
|
|
5597
5920
|
c.tsw.WriteLiterally("elemType: ")
|
|
5598
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
|
+
|
|
5599
5991
|
c.tsw.WriteLiterally("}")
|
|
5600
5992
|
default:
|
|
5601
5993
|
// For other types, use the string representation
|