goscript 0.0.2
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/.aider-prompt +11 -0
- package/LICENSE +21 -0
- package/README.md +427 -0
- package/builtin/builtin.ts +507 -0
- package/cmd/goscript/cmd_compile.go +59 -0
- package/cmd/goscript/main.go +23 -0
- package/compiler/compile.go +183 -0
- package/compiler/compile_comment.go +41 -0
- package/compiler/compile_decls.go +72 -0
- package/compiler/compile_expr.go +831 -0
- package/compiler/compile_field.go +89 -0
- package/compiler/compile_spec.go +256 -0
- package/compiler/compile_stmt.go +1509 -0
- package/compiler/compiler.go +81 -0
- package/compiler/config.go +32 -0
- package/compiler/context.go +9 -0
- package/compiler/file_compiler.go +80 -0
- package/compiler/output_path.go +31 -0
- package/compiler/pkg_compiler.go +73 -0
- package/compiler/writer.go +90 -0
- package/compliance/COMPLIANCE.md +133 -0
- package/compliance/compliance.go +313 -0
- package/compliance/compliance_test.go +57 -0
- package/compliance/tests/array_literal/array_literal.go +15 -0
- package/compliance/tests/array_literal/array_literal.gs.ts +19 -0
- package/compliance/tests/array_literal/expected.log +3 -0
- package/compliance/tests/async_basic/async_basic.go +26 -0
- package/compliance/tests/async_basic/async_basic.gs.ts +30 -0
- package/compliance/tests/async_basic/expected.log +1 -0
- package/compliance/tests/basic_arithmetic/basic_arithmetic.go +15 -0
- package/compliance/tests/basic_arithmetic/basic_arithmetic.gs.ts +19 -0
- package/compliance/tests/basic_arithmetic/expected.log +5 -0
- package/compliance/tests/boolean_logic/boolean_logic.go +13 -0
- package/compliance/tests/boolean_logic/boolean_logic.gs.ts +17 -0
- package/compliance/tests/boolean_logic/expected.log +3 -0
- package/compliance/tests/channel_basic/channel_basic.go +12 -0
- package/compliance/tests/channel_basic/channel_basic.gs.ts +18 -0
- package/compliance/tests/channel_basic/expected.log +1 -0
- package/compliance/tests/composite_literal_assignment/composite_literal_assignment.go +20 -0
- package/compliance/tests/composite_literal_assignment/composite_literal_assignment.gs.ts +27 -0
- package/compliance/tests/composite_literal_assignment/expected.log +2 -0
- package/compliance/tests/constants/constants.go +18 -0
- package/compliance/tests/constants/constants.gs.ts +22 -0
- package/compliance/tests/constants/expected.log +3 -0
- package/compliance/tests/copy_independence/copy_independence.go +29 -0
- package/compliance/tests/copy_independence/copy_independence.gs.ts +36 -0
- package/compliance/tests/copy_independence/expected.log +4 -0
- package/compliance/tests/float64/expected.log +6 -0
- package/compliance/tests/float64/float64.go +28 -0
- package/compliance/tests/float64/float64.gs.ts +32 -0
- package/compliance/tests/for_loop_basic/expected.log +5 -0
- package/compliance/tests/for_loop_basic/for_loop_basic.go +9 -0
- package/compliance/tests/for_loop_basic/for_loop_basic.gs.ts +13 -0
- package/compliance/tests/for_loop_condition_only/expected.log +5 -0
- package/compliance/tests/for_loop_condition_only/main.go +9 -0
- package/compliance/tests/for_loop_condition_only/main.gs.ts +13 -0
- package/compliance/tests/for_range/expected.log +9 -0
- package/compliance/tests/for_range/for_range.go +26 -0
- package/compliance/tests/for_range/for_range.gs.ts +45 -0
- package/compliance/tests/for_range_index_use/expected.log +6 -0
- package/compliance/tests/for_range_index_use/for_range_index_use.go +11 -0
- package/compliance/tests/for_range_index_use/for_range_index_use.gs.ts +18 -0
- package/compliance/tests/func_literal/expected.log +1 -0
- package/compliance/tests/func_literal/func_literal.go +10 -0
- package/compliance/tests/func_literal/func_literal.gs.ts +15 -0
- package/compliance/tests/function_call_result_assignment/expected.log +2 -0
- package/compliance/tests/function_call_result_assignment/function_call_result_assignment.go +24 -0
- package/compliance/tests/function_call_result_assignment/function_call_result_assignment.gs.ts +31 -0
- package/compliance/tests/if_statement/expected.log +1 -0
- package/compliance/tests/if_statement/if_statement.go +11 -0
- package/compliance/tests/if_statement/if_statement.gs.ts +15 -0
- package/compliance/tests/interface_to_interface_type_assertion/expected.log +1 -0
- package/compliance/tests/interface_to_interface_type_assertion/interface_to_interface_type_assertion.go +30 -0
- package/compliance/tests/interface_to_interface_type_assertion/interface_to_interface_type_assertion.gs.ts +41 -0
- package/compliance/tests/interface_type_assertion/expected.log +1 -0
- package/compliance/tests/interface_type_assertion/interface_type_assertion.go +26 -0
- package/compliance/tests/interface_type_assertion/interface_type_assertion.gs.ts +36 -0
- package/compliance/tests/map_support/expected.log +13 -0
- package/compliance/tests/map_support/map_support.go +89 -0
- package/compliance/tests/map_support/map_support.gs.ts +102 -0
- package/compliance/tests/method_call_on_pointer_receiver/expected.log +1 -0
- package/compliance/tests/method_call_on_pointer_receiver/method_call_on_pointer_receiver.go +19 -0
- package/compliance/tests/method_call_on_pointer_receiver/method_call_on_pointer_receiver.gs.ts +27 -0
- package/compliance/tests/method_call_on_pointer_via_value/expected.log +1 -0
- package/compliance/tests/method_call_on_pointer_via_value/method_call_on_pointer_via_value.go +29 -0
- package/compliance/tests/method_call_on_pointer_via_value/method_call_on_pointer_via_value.gs.ts +38 -0
- package/compliance/tests/method_call_on_value_receiver/expected.log +1 -0
- package/compliance/tests/method_call_on_value_receiver/method_call_on_value_receiver.go +16 -0
- package/compliance/tests/method_call_on_value_receiver/method_call_on_value_receiver.gs.ts +24 -0
- package/compliance/tests/method_call_on_value_via_pointer/expected.log +2 -0
- package/compliance/tests/method_call_on_value_via_pointer/method_call_on_value_via_pointer.go +30 -0
- package/compliance/tests/method_call_on_value_via_pointer/method_call_on_value_via_pointer.gs.ts +38 -0
- package/compliance/tests/multiple_return_values/expected.log +6 -0
- package/compliance/tests/multiple_return_values/multiple_return_values.go +19 -0
- package/compliance/tests/multiple_return_values/multiple_return_values.gs.ts +23 -0
- package/compliance/tests/pointer_assignment_no_copy/expected.log +2 -0
- package/compliance/tests/pointer_assignment_no_copy/pointer_assignment_no_copy.go +28 -0
- package/compliance/tests/pointer_assignment_no_copy/pointer_assignment_no_copy.gs.ts +35 -0
- package/compliance/tests/pointer_composite_literal_assignment/expected.log +3 -0
- package/compliance/tests/pointer_composite_literal_assignment/pointer_composite_literal_assignment.go +23 -0
- package/compliance/tests/pointer_composite_literal_assignment/pointer_composite_literal_assignment.gs.ts +30 -0
- package/compliance/tests/pointer_deref_multiassign/expected.log +0 -0
- package/compliance/tests/pointer_deref_multiassign/pointer_deref_multiassign.go +17 -0
- package/compliance/tests/pointer_deref_multiassign/pointer_deref_multiassign.gs.ts +27 -0
- package/compliance/tests/pointer_initialization/expected.log +1 -0
- package/compliance/tests/pointer_initialization/pointer_initialization.go +16 -0
- package/compliance/tests/pointer_initialization/pointer_initialization.gs.ts +22 -0
- package/compliance/tests/select_receive_on_closed_channel_no_default/expected.log +1 -0
- package/compliance/tests/select_receive_on_closed_channel_no_default/select_receive_on_closed_channel_no_default.go +15 -0
- package/compliance/tests/select_receive_on_closed_channel_no_default/select_receive_on_closed_channel_no_default.gs.ts +31 -0
- package/compliance/tests/select_send_on_full_buffered_channel_with_default/expected.log +1 -0
- package/compliance/tests/select_send_on_full_buffered_channel_with_default/select_send_on_full_buffered_channel_with_default.go +13 -0
- package/compliance/tests/select_send_on_full_buffered_channel_with_default/select_send_on_full_buffered_channel_with_default.gs.ts +35 -0
- package/compliance/tests/select_statement/expected.log +9 -0
- package/compliance/tests/select_statement/select_statement.go +109 -0
- package/compliance/tests/select_statement/select_statement.gs.ts +239 -0
- package/compliance/tests/simple/expected.log +1 -0
- package/compliance/tests/simple/simple.go +5 -0
- package/compliance/tests/simple/simple.gs.ts +9 -0
- package/compliance/tests/simple_deref_assignment/expected.log +2 -0
- package/compliance/tests/simple_deref_assignment/simple_deref_assignment.go +19 -0
- package/compliance/tests/simple_deref_assignment/simple_deref_assignment.gs.ts +26 -0
- package/compliance/tests/slices/expected.log +7 -0
- package/compliance/tests/slices/slices.go +22 -0
- package/compliance/tests/slices/slices.gs.ts +26 -0
- package/compliance/tests/string_rune_conversion/expected.log +3 -0
- package/compliance/tests/string_rune_conversion/string_rune_conversion.go +16 -0
- package/compliance/tests/string_rune_conversion/string_rune_conversion.gs.ts +22 -0
- package/compliance/tests/struct_field_access/expected.log +2 -0
- package/compliance/tests/struct_field_access/struct_field_access.go +13 -0
- package/compliance/tests/struct_field_access/struct_field_access.gs.ts +20 -0
- package/compliance/tests/struct_value_init_clone/expected.log +5 -0
- package/compliance/tests/struct_value_init_clone/struct_value_init_clone.go +28 -0
- package/compliance/tests/struct_value_init_clone/struct_value_init_clone.gs.ts +35 -0
- package/compliance/tests/switch_statement/expected.log +14 -0
- package/compliance/tests/switch_statement/switch_statement.go +59 -0
- package/compliance/tests/switch_statement/switch_statement.gs.ts +85 -0
- package/compliance/tests/value_type_copy_behavior/expected.log +3 -0
- package/compliance/tests/value_type_copy_behavior/value_type_copy_behavior.go +25 -0
- package/compliance/tests/value_type_copy_behavior/value_type_copy_behavior.gs.ts +34 -0
- package/design/DESIGN.md +599 -0
- package/example/simple/build.bash +10 -0
- package/example/simple/go.mod +23 -0
- package/example/simple/go.sum +39 -0
- package/example/simple/main.go +138 -0
- package/example/simple/main.gs.ts +133 -0
- package/example/simple/main.ts +3 -0
- package/example/simple/main_test.go +59 -0
- package/example/simple/main_tools.go +5 -0
- package/example/simple/package.json +7 -0
- package/example/simple/run.bash +6 -0
- package/example/simple/tsconfig.json +28 -0
- package/example/simple/yarn.lock +8 -0
- package/go.mod +22 -0
- package/go.sum +39 -0
- package/output/output.go +10 -0
- package/package.json +14 -0
- package/tsconfig.json +10 -0
- package/types/tokens.go +65 -0
- package/types/types.go +46 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
package compiler
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"go/ast"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
// WriteFieldList writes a field list.
|
|
9
|
+
func (c *GoToTSCompiler) WriteFieldList(a *ast.FieldList, isArguments bool) {
|
|
10
|
+
if !isArguments && (a == nil || a.NumFields() == 0) {
|
|
11
|
+
c.tsw.WriteLiterally("{}")
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if !isArguments && a.Opening.IsValid() {
|
|
16
|
+
c.tsw.WriteLine("{")
|
|
17
|
+
c.tsw.Indent(1)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Handle parameter list for function declarations
|
|
21
|
+
for i, field := range a.List {
|
|
22
|
+
if i > 0 && isArguments {
|
|
23
|
+
c.tsw.WriteLiterally(", ")
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if isArguments {
|
|
27
|
+
// For function parameters, write "name: type"
|
|
28
|
+
c.WriteField(field, true)
|
|
29
|
+
c.tsw.WriteLiterally(": ")
|
|
30
|
+
c.WriteTypeExpr(field.Type) // Use WriteTypeExpr for parameter type
|
|
31
|
+
} else {
|
|
32
|
+
// For struct fields and other non-argument fields
|
|
33
|
+
c.WriteField(field, false)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if !isArguments && a.Closing.IsValid() {
|
|
38
|
+
c.tsw.Indent(-1)
|
|
39
|
+
c.tsw.WriteLine("}")
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// WriteField writes a field definition.
|
|
44
|
+
func (c *GoToTSCompiler) WriteField(field *ast.Field, isArguments bool) {
|
|
45
|
+
if !isArguments {
|
|
46
|
+
if field.Doc != nil {
|
|
47
|
+
c.WriteDoc(field.Doc)
|
|
48
|
+
}
|
|
49
|
+
if field.Comment != nil {
|
|
50
|
+
c.WriteDoc(field.Comment)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for _, name := range field.Names {
|
|
54
|
+
isExported := name.IsExported()
|
|
55
|
+
|
|
56
|
+
// argument names: keep original casing, no access modifier
|
|
57
|
+
if isArguments {
|
|
58
|
+
c.tsw.WriteLiterally(name.Name)
|
|
59
|
+
// Argument type is handled in WriteFieldList, so continue
|
|
60
|
+
continue
|
|
61
|
+
} else if isExported {
|
|
62
|
+
// exported struct fields become public, keep original casing
|
|
63
|
+
c.tsw.WriteLiterally("public ")
|
|
64
|
+
c.tsw.WriteLiterally(name.Name)
|
|
65
|
+
} else {
|
|
66
|
+
// unexported struct fields become private, keep original casing
|
|
67
|
+
c.tsw.WriteLiterally("private ")
|
|
68
|
+
c.tsw.WriteLiterally(name.Name)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// write type for struct fields (not arguments)
|
|
72
|
+
c.tsw.WriteLiterally(": ")
|
|
73
|
+
c.WriteTypeExpr(field.Type) // Use WriteTypeExpr for field type
|
|
74
|
+
|
|
75
|
+
if !isArguments {
|
|
76
|
+
// write initializer with zero value for struct fields
|
|
77
|
+
c.tsw.WriteLiterally(" = ")
|
|
78
|
+
c.WriteZeroValueForType(field.Type)
|
|
79
|
+
|
|
80
|
+
// write tag comment if any for struct fields
|
|
81
|
+
if field.Tag != nil {
|
|
82
|
+
c.tsw.WriteLiterally(";")
|
|
83
|
+
c.tsw.WriteCommentLine(fmt.Sprintf("tag: %s", field.Tag.Value))
|
|
84
|
+
} else {
|
|
85
|
+
c.tsw.WriteLine(";")
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
package compiler
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"go/ast"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
// WriteSpec writes a specification to the output.
|
|
9
|
+
func (c *GoToTSCompiler) WriteSpec(a ast.Spec) error {
|
|
10
|
+
switch d := a.(type) {
|
|
11
|
+
case *ast.ImportSpec:
|
|
12
|
+
c.WriteImportSpec(d)
|
|
13
|
+
case *ast.ValueSpec:
|
|
14
|
+
if err := c.WriteValueSpec(d); err != nil {
|
|
15
|
+
return err
|
|
16
|
+
}
|
|
17
|
+
case *ast.TypeSpec:
|
|
18
|
+
if err := c.WriteTypeSpec(d); err != nil {
|
|
19
|
+
return err
|
|
20
|
+
}
|
|
21
|
+
default:
|
|
22
|
+
return fmt.Errorf("unknown spec type: %T", a)
|
|
23
|
+
}
|
|
24
|
+
return nil
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// WriteTypeSpec writes the type specification to the output.
|
|
28
|
+
func (c *GoToTSCompiler) WriteTypeSpec(a *ast.TypeSpec) error {
|
|
29
|
+
if a.Doc != nil {
|
|
30
|
+
c.WriteDoc(a.Doc)
|
|
31
|
+
}
|
|
32
|
+
if a.Comment != nil {
|
|
33
|
+
c.WriteDoc(a.Comment)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
switch t := a.Type.(type) {
|
|
37
|
+
case *ast.StructType:
|
|
38
|
+
// write the class definition
|
|
39
|
+
c.tsw.WriteLiterally("class ")
|
|
40
|
+
if err := c.WriteValueExpr(a.Name); err != nil { // Class name is a value identifier
|
|
41
|
+
return err
|
|
42
|
+
}
|
|
43
|
+
c.tsw.WriteLine(" {")
|
|
44
|
+
c.tsw.Indent(1)
|
|
45
|
+
|
|
46
|
+
// className is the name of the class type
|
|
47
|
+
className := a.Name.Name
|
|
48
|
+
for _, field := range t.Fields.List {
|
|
49
|
+
c.WriteField(field, false)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Methods for this struct are discovered by scanning all package declarations.
|
|
53
|
+
// Future improvement: use pkg.TypesInfo.MethodSet (go/types) for direct method lookup.
|
|
54
|
+
for _, fileSyntax := range c.pkg.Syntax {
|
|
55
|
+
for _, decl := range fileSyntax.Decls {
|
|
56
|
+
funcDecl, isFunc := decl.(*ast.FuncDecl)
|
|
57
|
+
if !isFunc || funcDecl.Recv == nil || len(funcDecl.Recv.List) == 0 {
|
|
58
|
+
continue // Skip non-functions or functions without receivers
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Check if the receiver type matches the struct name
|
|
62
|
+
recvField := funcDecl.Recv.List[0]
|
|
63
|
+
recvType := recvField.Type
|
|
64
|
+
// Handle pointer receivers (*MyStruct) and value receivers (MyStruct)
|
|
65
|
+
if starExpr, ok := recvType.(*ast.StarExpr); ok {
|
|
66
|
+
recvType = starExpr.X // Get the type being pointed to
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Check if the receiver identifier name matches the current struct name
|
|
70
|
+
if ident, ok := recvType.(*ast.Ident); ok && ident.Name == className {
|
|
71
|
+
// Found a method for this struct
|
|
72
|
+
c.tsw.WriteLine("") // Add space between methods
|
|
73
|
+
if err := c.WriteFuncDeclAsMethod(funcDecl); err != nil {
|
|
74
|
+
return err
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// constructor and clone using Object.assign for compactness
|
|
81
|
+
c.tsw.WriteLine("")
|
|
82
|
+
c.tsw.WriteLinef("constructor(init?: Partial<%s>) { if (init) Object.assign(this, init as any); }", className)
|
|
83
|
+
c.tsw.WriteLinef("public clone(): %s { return Object.assign(Object.create(%s.prototype) as %s, this); }", className, className, className)
|
|
84
|
+
c.tsw.Indent(-1)
|
|
85
|
+
c.tsw.WriteLine("}")
|
|
86
|
+
case *ast.InterfaceType:
|
|
87
|
+
c.tsw.WriteLiterally("interface ")
|
|
88
|
+
if err := c.WriteValueExpr(a.Name); err != nil { // Interface name is a value identifier
|
|
89
|
+
return err
|
|
90
|
+
}
|
|
91
|
+
c.tsw.WriteLine(" ")
|
|
92
|
+
c.WriteTypeExpr(a.Type) // The interface definition itself is a type
|
|
93
|
+
default:
|
|
94
|
+
// type alias
|
|
95
|
+
c.tsw.WriteLiterally("type ")
|
|
96
|
+
if err := c.WriteValueExpr(a.Name); err != nil { // Type alias name is a value identifier
|
|
97
|
+
return err
|
|
98
|
+
}
|
|
99
|
+
c.tsw.WriteLiterally(" = ")
|
|
100
|
+
c.WriteTypeExpr(a.Type) // The aliased type
|
|
101
|
+
c.tsw.WriteLine(";")
|
|
102
|
+
}
|
|
103
|
+
return nil
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// WriteFuncDeclAsMethod writes a TypeScript method declaration from a Go FuncDecl.
|
|
107
|
+
// Assumes it's called only for functions with receivers.
|
|
108
|
+
func (c *GoToTSCompiler) WriteFuncDeclAsMethod(decl *ast.FuncDecl) error {
|
|
109
|
+
if decl.Doc != nil {
|
|
110
|
+
c.WriteDoc(decl.Doc)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Methods are typically public in the TS output
|
|
114
|
+
c.tsw.WriteLiterally("public ")
|
|
115
|
+
// Keep original Go casing for method names
|
|
116
|
+
if err := c.WriteValueExpr(decl.Name); err != nil { // Method name is a value identifier
|
|
117
|
+
return err
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Write signature (parameters and return type)
|
|
121
|
+
// We adapt the logic from WriteFuncType here, but without the 'function' keyword
|
|
122
|
+
funcType := decl.Type
|
|
123
|
+
c.tsw.WriteLiterally("(")
|
|
124
|
+
if funcType.Params != nil {
|
|
125
|
+
c.WriteFieldList(funcType.Params, true) // true = arguments
|
|
126
|
+
}
|
|
127
|
+
c.tsw.WriteLiterally(")")
|
|
128
|
+
|
|
129
|
+
// Handle return type
|
|
130
|
+
if funcType.Results != nil && len(funcType.Results.List) > 0 {
|
|
131
|
+
c.tsw.WriteLiterally(": ")
|
|
132
|
+
if len(funcType.Results.List) == 1 {
|
|
133
|
+
// Single return value
|
|
134
|
+
resultType := funcType.Results.List[0].Type
|
|
135
|
+
c.WriteTypeExpr(resultType)
|
|
136
|
+
} else {
|
|
137
|
+
// Multiple return values -> tuple type
|
|
138
|
+
c.tsw.WriteLiterally("[")
|
|
139
|
+
for i, field := range funcType.Results.List {
|
|
140
|
+
if i > 0 {
|
|
141
|
+
c.tsw.WriteLiterally(", ")
|
|
142
|
+
}
|
|
143
|
+
c.WriteTypeExpr(field.Type)
|
|
144
|
+
}
|
|
145
|
+
c.tsw.WriteLiterally("]")
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
// No return value -> void
|
|
149
|
+
c.tsw.WriteLiterally(": void")
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
c.tsw.WriteLiterally(" ")
|
|
153
|
+
// Bind receiver name to this
|
|
154
|
+
if recvField := decl.Recv.List[0]; len(recvField.Names) > 0 {
|
|
155
|
+
recvName := recvField.Names[0].Name
|
|
156
|
+
if recvName != "_" {
|
|
157
|
+
c.tsw.WriteLine("{")
|
|
158
|
+
c.tsw.Indent(1)
|
|
159
|
+
c.tsw.WriteLinef("const %s = this", recvName)
|
|
160
|
+
// write method body without outer braces
|
|
161
|
+
for _, stmt := range decl.Body.List {
|
|
162
|
+
if err := c.WriteStmt(stmt); err != nil {
|
|
163
|
+
return fmt.Errorf("failed to write statement in function body: %w", err)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
c.tsw.Indent(-1)
|
|
167
|
+
c.tsw.WriteLine("}")
|
|
168
|
+
return nil
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// no named receiver, write whole body
|
|
172
|
+
if err := c.WriteStmt(decl.Body); err != nil {
|
|
173
|
+
return fmt.Errorf("failed to write function body: %w", err)
|
|
174
|
+
}
|
|
175
|
+
return nil
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// WriteValueSpec writes the value specification to the output.
|
|
179
|
+
func (c *GoToTSCompiler) WriteValueSpec(a *ast.ValueSpec) error {
|
|
180
|
+
if a.Doc != nil {
|
|
181
|
+
c.WriteDoc(a.Doc)
|
|
182
|
+
}
|
|
183
|
+
if a.Comment != nil {
|
|
184
|
+
c.WriteDoc(a.Comment)
|
|
185
|
+
}
|
|
186
|
+
c.tsw.WriteLiterally("let ")
|
|
187
|
+
if len(a.Names) == 1 {
|
|
188
|
+
name := a.Names[0]
|
|
189
|
+
c.tsw.WriteLiterally(name.Name)
|
|
190
|
+
if a.Type != nil {
|
|
191
|
+
c.tsw.WriteLiterally(": ")
|
|
192
|
+
c.WriteTypeExpr(a.Type) // Variable type annotation
|
|
193
|
+
|
|
194
|
+
// Check if it's an array type declaration without an initial value
|
|
195
|
+
if _, isArrayType := a.Type.(*ast.ArrayType); isArrayType && len(a.Values) == 0 {
|
|
196
|
+
c.tsw.WriteLiterally(" = []")
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if len(a.Values) > 0 {
|
|
200
|
+
c.tsw.WriteLiterally(" = ")
|
|
201
|
+
for i, val := range a.Values {
|
|
202
|
+
if i != 0 {
|
|
203
|
+
c.tsw.WriteLiterally(", ")
|
|
204
|
+
}
|
|
205
|
+
if err := c.WriteValueExpr(val); err != nil { // Initializer is a value
|
|
206
|
+
return err
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
c.tsw.WriteLiterally("{")
|
|
212
|
+
for i, name := range a.Names {
|
|
213
|
+
if i != 0 {
|
|
214
|
+
c.tsw.WriteLiterally(", ")
|
|
215
|
+
}
|
|
216
|
+
c.tsw.WriteLiterally(name.Name)
|
|
217
|
+
}
|
|
218
|
+
c.tsw.WriteLiterally("}")
|
|
219
|
+
for i, val := range a.Values {
|
|
220
|
+
if i == 0 {
|
|
221
|
+
c.tsw.WriteLiterally(" = ")
|
|
222
|
+
} else {
|
|
223
|
+
c.tsw.WriteLiterally(", ")
|
|
224
|
+
}
|
|
225
|
+
if err := c.WriteValueExpr(val); err != nil { // Initializers are values
|
|
226
|
+
return err
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
c.tsw.WriteLine(";")
|
|
231
|
+
return nil
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// WriteImportSpec writes an import specification to the output.
|
|
235
|
+
func (c *GoToTSCompiler) WriteImportSpec(a *ast.ImportSpec) {
|
|
236
|
+
if a.Doc != nil {
|
|
237
|
+
c.WriteDoc(a.Doc)
|
|
238
|
+
}
|
|
239
|
+
if a.Comment != nil {
|
|
240
|
+
c.WriteDoc(a.Comment)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
goPath := a.Path.Value[1 : len(a.Path.Value)-1]
|
|
244
|
+
impName := packageNameFromGoPath(goPath)
|
|
245
|
+
if a.Name != nil && a.Name.Name != "" {
|
|
246
|
+
impName = a.Name.Name
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
importPath := translateGoPathToTypescriptPath(goPath)
|
|
250
|
+
c.imports[impName] = &fileImport{
|
|
251
|
+
importPath: importPath,
|
|
252
|
+
importVars: make(map[string]struct{}),
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
c.tsw.WriteImport(impName, importPath)
|
|
256
|
+
}
|