goscript 0.0.78 → 0.0.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiler/analysis.go +24 -25
- package/compiler/decl.go +0 -34
- package/compiler/spec-struct.go +237 -13
- package/compiler/spec.go +0 -7
- package/package.json +1 -1
package/compiler/analysis.go
CHANGED
|
@@ -2756,23 +2756,25 @@ func (v *analysisVisitor) analyzeAllMethodsAsync() {
|
|
|
2756
2756
|
// Topologically sort methods by their dependencies
|
|
2757
2757
|
sorted, cycles := v.topologicalSortMethods(methodCalls)
|
|
2758
2758
|
|
|
2759
|
-
//
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
//
|
|
2759
|
+
// Analyze methods in dependency order (dependencies analyzed before dependents)
|
|
2760
|
+
for _, methodKey := range sorted {
|
|
2761
|
+
v.analyzeMethodAsyncTopological(methodKey, methodCalls[methodKey])
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
// Analyze methods in cycles after the acyclic portion of the graph is known.
|
|
2765
|
+
// This lets recursive methods observe async callees outside the cycle while
|
|
2766
|
+
// still converging over recursive edges inside the cycle.
|
|
2765
2767
|
maxIterations := 10
|
|
2766
2768
|
for range maxIterations {
|
|
2767
2769
|
changed := false
|
|
2768
2770
|
|
|
2769
2771
|
for _, methodKey := range cycles {
|
|
2770
|
-
// For methods in cycles, we need to check their body directly for async operations
|
|
2771
2772
|
pkg := v.analysis.AllPackages[methodKey.PackagePath]
|
|
2772
2773
|
if pkg == nil && methodKey.PackagePath == v.pkg.Types.Path() {
|
|
2773
2774
|
pkg = v.pkg
|
|
2774
2775
|
}
|
|
2775
2776
|
|
|
2777
|
+
isAsync := false
|
|
2776
2778
|
if pkg != nil {
|
|
2777
2779
|
var funcDecl *ast.FuncDecl
|
|
2778
2780
|
if methodKey.ReceiverType == "" {
|
|
@@ -2782,37 +2784,29 @@ func (v *analysisVisitor) analyzeAllMethodsAsync() {
|
|
|
2782
2784
|
}
|
|
2783
2785
|
|
|
2784
2786
|
if funcDecl != nil && funcDecl.Body != nil {
|
|
2785
|
-
|
|
2786
|
-
isAsync
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2787
|
+
isAsync = v.containsAsyncOperationsComplete(funcDecl.Body, pkg)
|
|
2788
|
+
if !isAsync {
|
|
2789
|
+
for _, callee := range methodCalls[methodKey] {
|
|
2790
|
+
if calleeAsync, exists := v.analysis.MethodAsyncStatus[callee]; exists && calleeAsync {
|
|
2791
|
+
isAsync = true
|
|
2792
|
+
break
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2791
2795
|
}
|
|
2792
|
-
|
|
2793
|
-
v.analysis.MethodAsyncStatus[methodKey] = isAsync
|
|
2794
|
-
continue
|
|
2795
2796
|
}
|
|
2796
2797
|
}
|
|
2797
2798
|
|
|
2798
|
-
|
|
2799
|
-
if _, exists := v.analysis.MethodAsyncStatus[methodKey]; !exists {
|
|
2800
|
-
v.analysis.MethodAsyncStatus[methodKey] = false
|
|
2799
|
+
if oldStatus, exists := v.analysis.MethodAsyncStatus[methodKey]; !exists || oldStatus != isAsync {
|
|
2801
2800
|
changed = true
|
|
2802
2801
|
}
|
|
2802
|
+
v.analysis.MethodAsyncStatus[methodKey] = isAsync
|
|
2803
2803
|
}
|
|
2804
2804
|
|
|
2805
|
-
// If no changes in this iteration, we're done
|
|
2806
2805
|
if !changed {
|
|
2807
2806
|
break
|
|
2808
2807
|
}
|
|
2809
2808
|
}
|
|
2810
2809
|
|
|
2811
|
-
// Analyze methods in dependency order (dependencies analyzed before dependents)
|
|
2812
|
-
for _, methodKey := range sorted {
|
|
2813
|
-
v.analyzeMethodAsyncTopological(methodKey, methodCalls[methodKey])
|
|
2814
|
-
}
|
|
2815
|
-
|
|
2816
2810
|
// Track async-returning variables BEFORE analyzing function literals
|
|
2817
2811
|
// This detects variables assigned from higher-order functions with async function literal args
|
|
2818
2812
|
// e.g., indirect := sync.OnceValue(asyncFunc)
|
|
@@ -3259,6 +3253,11 @@ func (v *analysisVisitor) containsAsyncOperationsComplete(node ast.Node, pkg *pa
|
|
|
3259
3253
|
if n == nil {
|
|
3260
3254
|
return false
|
|
3261
3255
|
}
|
|
3256
|
+
if n != node {
|
|
3257
|
+
if _, ok := n.(*ast.FuncLit); ok {
|
|
3258
|
+
return false
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3262
3261
|
|
|
3263
3262
|
switch s := n.(type) {
|
|
3264
3263
|
case *ast.SendStmt:
|
package/compiler/decl.go
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package compiler
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
"bytes"
|
|
5
4
|
"fmt"
|
|
6
5
|
"go/ast"
|
|
7
6
|
"go/token"
|
|
@@ -678,14 +677,6 @@ func (c *GoToTSCompiler) writeMethodSignature(decl *ast.FuncDecl) (bool, error)
|
|
|
678
677
|
}
|
|
679
678
|
}
|
|
680
679
|
|
|
681
|
-
if !isAsync {
|
|
682
|
-
bodyNeedsAsync, err := c.funcBodyNeedsAsync(decl, true)
|
|
683
|
-
if err != nil {
|
|
684
|
-
return false, err
|
|
685
|
-
}
|
|
686
|
-
isAsync = bodyNeedsAsync
|
|
687
|
-
}
|
|
688
|
-
|
|
689
680
|
// Methods are typically public in the TS output
|
|
690
681
|
c.tsw.WriteLiterally("public ")
|
|
691
682
|
|
|
@@ -753,31 +744,6 @@ func (c *GoToTSCompiler) writeMethodSignature(decl *ast.FuncDecl) (bool, error)
|
|
|
753
744
|
return isAsync, nil
|
|
754
745
|
}
|
|
755
746
|
|
|
756
|
-
// funcBodyNeedsAsync checks whether emitting a function body would generate await.
|
|
757
|
-
func (c *GoToTSCompiler) funcBodyNeedsAsync(decl *ast.FuncDecl, isMethod bool) (bool, error) {
|
|
758
|
-
if decl.Body == nil {
|
|
759
|
-
return false, nil
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
var body strings.Builder
|
|
763
|
-
writer := NewTSCodeWriter(&body)
|
|
764
|
-
tempCompiler := NewGoToTSCompiler(writer, c.pkg, c.analysis, c.currentFilePath)
|
|
765
|
-
|
|
766
|
-
if isMethod {
|
|
767
|
-
if err := tempCompiler.writeMethodBodyWithReceiverBinding(decl, "this"); err != nil {
|
|
768
|
-
return false, err
|
|
769
|
-
}
|
|
770
|
-
} else {
|
|
771
|
-
for _, stmt := range decl.Body.List {
|
|
772
|
-
if err := tempCompiler.WriteStmt(stmt); err != nil {
|
|
773
|
-
return false, err
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
return bytes.Contains([]byte(body.String()), []byte("await")), nil
|
|
779
|
-
}
|
|
780
|
-
|
|
781
747
|
// writeMethodBodyWithReceiverBinding writes the method body with optional receiver binding
|
|
782
748
|
// receiverTarget should be "this" for struct methods or "this._value" for named type methods
|
|
783
749
|
func (c *GoToTSCompiler) writeMethodBodyWithReceiverBinding(decl *ast.FuncDecl, receiverTarget string) error {
|
package/compiler/spec-struct.go
CHANGED
|
@@ -513,7 +513,8 @@ func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType)
|
|
|
513
513
|
}
|
|
514
514
|
|
|
515
515
|
// WriteNamedStructTypeSpec generates a TypeScript class for a named type whose
|
|
516
|
-
// underlying type is
|
|
516
|
+
// underlying type is another named struct. The emitted class copies the field
|
|
517
|
+
// layout without inheriting the underlying named type's prototype methods.
|
|
517
518
|
func (c *GoToTSCompiler) WriteNamedStructTypeSpec(a *ast.TypeSpec, named *types.Named) error {
|
|
518
519
|
isInsideFunction := false
|
|
519
520
|
if nodeInfo := c.analysis.NodeData[a]; nodeInfo != nil {
|
|
@@ -531,8 +532,6 @@ func (c *GoToTSCompiler) WriteNamedStructTypeSpec(a *ast.TypeSpec, named *types.
|
|
|
531
532
|
c.WriteTypeParameters(a.TypeParams)
|
|
532
533
|
}
|
|
533
534
|
|
|
534
|
-
c.tsw.WriteLiterally(" extends ")
|
|
535
|
-
c.WriteTypeExpr(a.Type)
|
|
536
535
|
c.tsw.WriteLiterally(" ")
|
|
537
536
|
c.tsw.WriteLine("{")
|
|
538
537
|
c.tsw.Indent(1)
|
|
@@ -543,16 +542,77 @@ func (c *GoToTSCompiler) WriteNamedStructTypeSpec(a *ast.TypeSpec, named *types.
|
|
|
543
542
|
return fmt.Errorf("underlying type of %s is not a struct", a.Name.Name)
|
|
544
543
|
}
|
|
545
544
|
|
|
546
|
-
c.
|
|
545
|
+
underlyingType := c.pkg.TypesInfo.TypeOf(a.Type)
|
|
546
|
+
underlyingInitType := "{}"
|
|
547
|
+
if underlyingNamed, ok := underlyingType.(*types.Named); ok {
|
|
548
|
+
underlyingInitType = c.generateFlattenedInitTypeString(underlyingNamed, nil)
|
|
549
|
+
}
|
|
550
|
+
underlyingTypeName := c.getASTTypeString(a.Type, underlyingType)
|
|
551
|
+
|
|
552
|
+
for i := 0; i < underlyingStruct.NumFields(); i++ {
|
|
553
|
+
field := underlyingStruct.Field(i)
|
|
554
|
+
if field.Anonymous() {
|
|
555
|
+
continue
|
|
556
|
+
}
|
|
557
|
+
if !field.Exported() && field.Pkg() != c.pkg.Types {
|
|
558
|
+
continue
|
|
559
|
+
}
|
|
560
|
+
c.writeGetterSetter(field.Name(), field.Type(), nil, nil, nil)
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
for field := range underlyingStruct.Fields() {
|
|
564
|
+
if field.Anonymous() {
|
|
565
|
+
fieldKeyName := c.getEmbeddedFieldKeyName(field.Type())
|
|
566
|
+
c.writeGetterSetter(fieldKeyName, field.Type(), nil, nil, nil)
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
c.tsw.WriteLiterally("public _fields: {")
|
|
547
571
|
c.tsw.Indent(1)
|
|
548
|
-
c.tsw.WriteLine("
|
|
572
|
+
c.tsw.WriteLine("")
|
|
573
|
+
for i := 0; i < underlyingStruct.NumFields(); i++ {
|
|
574
|
+
field := underlyingStruct.Field(i)
|
|
575
|
+
fieldKeyName := field.Name()
|
|
576
|
+
if field.Anonymous() {
|
|
577
|
+
fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
|
|
578
|
+
}
|
|
579
|
+
if fieldKeyName == "_" {
|
|
580
|
+
continue
|
|
581
|
+
}
|
|
582
|
+
c.tsw.WriteLinef("%s: $.VarRef<%s>;", fieldKeyName, c.getTypeString(field.Type()))
|
|
583
|
+
}
|
|
549
584
|
c.tsw.Indent(-1)
|
|
550
585
|
c.tsw.WriteLine("}")
|
|
551
586
|
c.tsw.WriteLine("")
|
|
552
587
|
|
|
553
|
-
c.tsw.WriteLinef("
|
|
588
|
+
c.tsw.WriteLinef("constructor(init?: Partial<%s>) {", underlyingInitType)
|
|
589
|
+
c.tsw.Indent(1)
|
|
590
|
+
c.tsw.WriteLinef("const base = new %s(init)", underlyingTypeName)
|
|
591
|
+
c.tsw.WriteLine("this._fields = base._fields")
|
|
592
|
+
c.tsw.Indent(-1)
|
|
593
|
+
c.tsw.WriteLine("}")
|
|
594
|
+
c.tsw.WriteLine("")
|
|
595
|
+
|
|
596
|
+
var cloneReturnType strings.Builder
|
|
597
|
+
cloneReturnType.WriteString(className)
|
|
598
|
+
if a.TypeParams != nil && len(a.TypeParams.List) > 0 {
|
|
599
|
+
cloneReturnType.WriteString("<")
|
|
600
|
+
first := true
|
|
601
|
+
for _, field := range a.TypeParams.List {
|
|
602
|
+
for _, name := range field.Names {
|
|
603
|
+
if !first {
|
|
604
|
+
cloneReturnType.WriteString(", ")
|
|
605
|
+
}
|
|
606
|
+
first = false
|
|
607
|
+
cloneReturnType.WriteString(name.Name)
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
cloneReturnType.WriteString(">")
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
c.tsw.WriteLinef("public clone(): %s {", cloneReturnType.String())
|
|
554
614
|
c.tsw.Indent(1)
|
|
555
|
-
c.tsw.WriteLinef("const cloned = new %s()",
|
|
615
|
+
c.tsw.WriteLinef("const cloned = new %s()", cloneReturnType.String())
|
|
556
616
|
c.tsw.WriteLine("cloned._fields = {")
|
|
557
617
|
c.tsw.Indent(1)
|
|
558
618
|
|
|
@@ -560,11 +620,9 @@ func (c *GoToTSCompiler) WriteNamedStructTypeSpec(a *ast.TypeSpec, named *types.
|
|
|
560
620
|
for i := 0; i < underlyingStruct.NumFields(); i++ {
|
|
561
621
|
field := underlyingStruct.Field(i)
|
|
562
622
|
fieldType := field.Type()
|
|
563
|
-
|
|
623
|
+
fieldKeyName := field.Name()
|
|
564
624
|
if field.Anonymous() {
|
|
565
625
|
fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
|
|
566
|
-
} else {
|
|
567
|
-
fieldKeyName = field.Name()
|
|
568
626
|
}
|
|
569
627
|
if fieldKeyName == "_" {
|
|
570
628
|
continue
|
|
@@ -615,6 +673,174 @@ func (c *GoToTSCompiler) WriteNamedStructTypeSpec(a *ast.TypeSpec, named *types.
|
|
|
615
673
|
}
|
|
616
674
|
}
|
|
617
675
|
|
|
676
|
+
seenPromotedFields := make(map[string]bool)
|
|
677
|
+
directMethods := make(map[string]bool)
|
|
678
|
+
for method := range named.Methods() {
|
|
679
|
+
sig := method.Type().(*types.Signature)
|
|
680
|
+
if sig.Recv() != nil {
|
|
681
|
+
recvType := sig.Recv().Type()
|
|
682
|
+
if namedRecv, ok := recvType.(*types.Named); ok && namedRecv.Obj() == named.Obj() {
|
|
683
|
+
directMethods[method.Name()] = true
|
|
684
|
+
} else if ptrRecv, ok := recvType.(*types.Pointer); ok {
|
|
685
|
+
if namedElem, ok := ptrRecv.Elem().(*types.Named); ok && namedElem.Obj() == named.Obj() {
|
|
686
|
+
directMethods[method.Name()] = true
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
for field := range underlyingStruct.Fields() {
|
|
693
|
+
if !field.Anonymous() {
|
|
694
|
+
continue
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
embeddedFieldType := field.Type()
|
|
698
|
+
embeddedFieldKeyName := c.getEmbeddedFieldKeyName(field.Type())
|
|
699
|
+
|
|
700
|
+
trueEmbeddedType := embeddedFieldType
|
|
701
|
+
if ptr, isPtr := trueEmbeddedType.(*types.Pointer); isPtr {
|
|
702
|
+
trueEmbeddedType = ptr.Elem()
|
|
703
|
+
}
|
|
704
|
+
if _, isNamed := trueEmbeddedType.(*types.Named); !isNamed {
|
|
705
|
+
continue
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
if namedEmbedded, ok := trueEmbeddedType.(*types.Named); ok {
|
|
709
|
+
if underlyingEmbeddedStruct, ok := namedEmbedded.Underlying().(*types.Struct); ok {
|
|
710
|
+
for promotedField := range underlyingEmbeddedStruct.Fields() {
|
|
711
|
+
if !promotedField.Exported() && promotedField.Pkg() != c.pkg.Types {
|
|
712
|
+
continue
|
|
713
|
+
}
|
|
714
|
+
promotedFieldName := promotedField.Name()
|
|
715
|
+
if seenPromotedFields[promotedFieldName] {
|
|
716
|
+
continue
|
|
717
|
+
}
|
|
718
|
+
conflict := false
|
|
719
|
+
for field := range underlyingStruct.Fields() {
|
|
720
|
+
if !field.Anonymous() && field.Name() == promotedFieldName {
|
|
721
|
+
conflict = true
|
|
722
|
+
break
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
if conflict {
|
|
726
|
+
continue
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
seenPromotedFields[promotedFieldName] = true
|
|
730
|
+
tsPromotedFieldType := c.getTypeString(promotedField.Type())
|
|
731
|
+
c.tsw.WriteLine("")
|
|
732
|
+
c.tsw.WriteLinef("public get %s(): %s {", promotedFieldName, tsPromotedFieldType)
|
|
733
|
+
c.tsw.Indent(1)
|
|
734
|
+
embeddedFieldTypeUnderlying := embeddedFieldType
|
|
735
|
+
if ptr, isPtr := embeddedFieldTypeUnderlying.(*types.Pointer); isPtr {
|
|
736
|
+
embeddedFieldTypeUnderlying = ptr.Elem()
|
|
737
|
+
}
|
|
738
|
+
if named, isNamed := embeddedFieldTypeUnderlying.(*types.Named); isNamed {
|
|
739
|
+
embeddedFieldTypeUnderlying = named.Underlying()
|
|
740
|
+
}
|
|
741
|
+
if _, isInterface := embeddedFieldTypeUnderlying.(*types.Interface); isInterface {
|
|
742
|
+
c.tsw.WriteLinef("return this.%s!.%s", embeddedFieldKeyName, promotedFieldName)
|
|
743
|
+
} else {
|
|
744
|
+
c.tsw.WriteLinef("return this.%s.%s", embeddedFieldKeyName, promotedFieldName)
|
|
745
|
+
}
|
|
746
|
+
c.tsw.Indent(-1)
|
|
747
|
+
c.tsw.WriteLine("}")
|
|
748
|
+
c.tsw.WriteLinef("public set %s(value: %s) {", promotedFieldName, tsPromotedFieldType)
|
|
749
|
+
c.tsw.Indent(1)
|
|
750
|
+
if _, isInterface := embeddedFieldTypeUnderlying.(*types.Interface); isInterface {
|
|
751
|
+
c.tsw.WriteLinef("this.%s!.%s = value", embeddedFieldKeyName, promotedFieldName)
|
|
752
|
+
} else {
|
|
753
|
+
c.tsw.WriteLinef("this.%s.%s = value", embeddedFieldKeyName, promotedFieldName)
|
|
754
|
+
}
|
|
755
|
+
c.tsw.Indent(-1)
|
|
756
|
+
c.tsw.WriteLine("}")
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
methodSetType := embeddedFieldType
|
|
762
|
+
if _, isPtr := embeddedFieldType.(*types.Pointer); !isPtr {
|
|
763
|
+
if _, isInterface := embeddedFieldType.Underlying().(*types.Interface); !isInterface {
|
|
764
|
+
methodSetType = types.NewPointer(embeddedFieldType)
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
embeddedMethodSet := types.NewMethodSet(methodSetType)
|
|
768
|
+
for methodSelection := range embeddedMethodSet.Methods() {
|
|
769
|
+
method := methodSelection.Obj().(*types.Func)
|
|
770
|
+
methodName := method.Name()
|
|
771
|
+
|
|
772
|
+
if len(methodSelection.Index()) == 1 && !directMethods[methodName] && !seenPromotedFields[methodName] {
|
|
773
|
+
conflictWithField := false
|
|
774
|
+
for field := range underlyingStruct.Fields() {
|
|
775
|
+
if !field.Anonymous() && field.Name() == methodName {
|
|
776
|
+
conflictWithField = true
|
|
777
|
+
break
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if conflictWithField {
|
|
781
|
+
continue
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
seenPromotedFields[methodName] = true
|
|
785
|
+
sig := method.Type().(*types.Signature)
|
|
786
|
+
c.tsw.WriteLine("")
|
|
787
|
+
c.tsw.WriteLiterally("public ")
|
|
788
|
+
c.tsw.WriteLiterally(methodName)
|
|
789
|
+
c.tsw.WriteLiterally("(")
|
|
790
|
+
params := sig.Params()
|
|
791
|
+
paramNames := make([]string, params.Len())
|
|
792
|
+
for j := 0; j < params.Len(); j++ {
|
|
793
|
+
param := params.At(j)
|
|
794
|
+
paramName := param.Name()
|
|
795
|
+
if paramName == "" || paramName == "_" {
|
|
796
|
+
paramName = fmt.Sprintf("_p%d", j)
|
|
797
|
+
}
|
|
798
|
+
paramNames[j] = paramName
|
|
799
|
+
if j > 0 {
|
|
800
|
+
c.tsw.WriteLiterally(", ")
|
|
801
|
+
}
|
|
802
|
+
c.tsw.WriteLiterally(paramName)
|
|
803
|
+
c.tsw.WriteLiterally(": ")
|
|
804
|
+
c.WriteGoType(param.Type(), GoTypeContextGeneral)
|
|
805
|
+
}
|
|
806
|
+
c.tsw.WriteLiterally(")")
|
|
807
|
+
results := sig.Results()
|
|
808
|
+
if results.Len() > 0 {
|
|
809
|
+
c.tsw.WriteLiterally(": ")
|
|
810
|
+
if results.Len() == 1 {
|
|
811
|
+
c.WriteGoType(results.At(0).Type(), GoTypeContextFunctionReturn)
|
|
812
|
+
} else {
|
|
813
|
+
c.tsw.WriteLiterally("[")
|
|
814
|
+
for j := 0; j < results.Len(); j++ {
|
|
815
|
+
if j > 0 {
|
|
816
|
+
c.tsw.WriteLiterally(", ")
|
|
817
|
+
}
|
|
818
|
+
c.WriteGoType(results.At(j).Type(), GoTypeContextFunctionReturn)
|
|
819
|
+
}
|
|
820
|
+
c.tsw.WriteLiterally("]")
|
|
821
|
+
}
|
|
822
|
+
} else {
|
|
823
|
+
c.tsw.WriteLiterally(": void")
|
|
824
|
+
}
|
|
825
|
+
c.tsw.WriteLine(" {")
|
|
826
|
+
c.tsw.Indent(1)
|
|
827
|
+
if results.Len() > 0 {
|
|
828
|
+
c.tsw.WriteLiterally("return ")
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
assertionPrefix := "this.%s"
|
|
832
|
+
if _, isInterface := embeddedFieldType.Underlying().(*types.Interface); isInterface {
|
|
833
|
+
assertionPrefix = "this.%s!"
|
|
834
|
+
}
|
|
835
|
+
c.tsw.WriteLiterallyf(assertionPrefix+".%s(%s)", embeddedFieldKeyName, methodName, strings.Join(paramNames, ", "))
|
|
836
|
+
|
|
837
|
+
c.tsw.WriteLine("")
|
|
838
|
+
c.tsw.Indent(-1)
|
|
839
|
+
c.tsw.WriteLine("}")
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
|
|
618
844
|
c.tsw.WriteLine("")
|
|
619
845
|
c.tsw.WriteLine("// Register this type with the runtime type system")
|
|
620
846
|
|
|
@@ -652,11 +878,9 @@ func (c *GoToTSCompiler) WriteNamedStructTypeSpec(a *ast.TypeSpec, named *types.
|
|
|
652
878
|
firstField := true
|
|
653
879
|
for i := 0; i < underlyingStruct.NumFields(); i++ {
|
|
654
880
|
field := underlyingStruct.Field(i)
|
|
655
|
-
|
|
881
|
+
fieldKeyName := field.Name()
|
|
656
882
|
if field.Anonymous() {
|
|
657
883
|
fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
|
|
658
|
-
} else {
|
|
659
|
-
fieldKeyName = field.Name()
|
|
660
884
|
}
|
|
661
885
|
if fieldKeyName == "_" {
|
|
662
886
|
continue
|
package/compiler/spec.go
CHANGED
|
@@ -370,13 +370,6 @@ func (c *GoToTSCompiler) WriteNamedTypeWithMethods(a *ast.TypeSpec) error {
|
|
|
370
370
|
if obj := c.pkg.TypesInfo.Defs[funcDecl.Name]; obj != nil {
|
|
371
371
|
isAsync = c.analysis.IsAsyncFunc(obj)
|
|
372
372
|
}
|
|
373
|
-
if !isAsync {
|
|
374
|
-
bodyNeedsAsync, err := c.funcBodyNeedsAsync(funcDecl, false)
|
|
375
|
-
if err != nil {
|
|
376
|
-
return err
|
|
377
|
-
}
|
|
378
|
-
isAsync = bodyNeedsAsync
|
|
379
|
-
}
|
|
380
373
|
if isAsync {
|
|
381
374
|
c.tsw.WriteLiterally("async ")
|
|
382
375
|
}
|