goscript 0.0.84 → 0.1.0
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/README.md +13 -1
- package/cmd/goscript/cmd_compile.go +70 -69
- package/cmd/goscript/cmd_compile_test.go +79 -0
- package/cmd/goscript/main.go +10 -5
- package/compiler/compile-request.go +218 -0
- package/compiler/compiler.go +16 -1336
- package/compiler/compliance_test.go +196 -0
- package/compiler/config.go +6 -13
- package/compiler/diagnostic.go +70 -0
- package/compiler/index.test.ts +28 -28
- package/compiler/index.ts +40 -72
- package/compiler/lowered-program.go +132 -0
- package/compiler/lowering.go +3576 -0
- package/compiler/override-registry.go +422 -0
- package/compiler/override-registry_test.go +207 -0
- package/compiler/package-graph.go +231 -0
- package/compiler/package-graph_test.go +281 -0
- package/compiler/result.go +13 -0
- package/compiler/runtime-contract.go +279 -0
- package/compiler/runtime-contract_test.go +90 -0
- package/compiler/semantic-model-types.go +110 -0
- package/compiler/semantic-model.go +922 -0
- package/compiler/semantic-model_test.go +416 -0
- package/compiler/service.go +133 -0
- package/compiler/skeleton_test.go +1145 -0
- package/compiler/typescript-emitter.go +663 -0
- package/compiler/wasm/compile.go +2 -3
- package/compiler/wasm/compile_test.go +29 -0
- package/compiler/wasm_api.go +10 -159
- package/dist/compiler/index.d.ts +1 -3
- package/dist/compiler/index.js +31 -55
- package/dist/compiler/index.js.map +1 -1
- package/dist/gs/builtin/builtin.d.ts +13 -0
- package/dist/gs/builtin/builtin.js +23 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +3 -3
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +15 -1
- package/dist/gs/builtin/hostio.js +134 -49
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/index.d.ts +1 -0
- package/dist/gs/builtin/index.js +1 -0
- package/dist/gs/builtin/index.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +1 -1
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +11 -0
- package/dist/gs/builtin/type.js +55 -1
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/bytes.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/rand/index.d.ts +5 -0
- package/dist/gs/crypto/rand/index.js +77 -0
- package/dist/gs/crypto/rand/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +3 -0
- package/dist/gs/encoding/json/index.js +160 -0
- package/dist/gs/encoding/json/index.js.map +1 -0
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +29 -0
- package/dist/gs/go/scanner/index.js +120 -0
- package/dist/gs/go/scanner/index.js.map +1 -0
- package/dist/gs/go/token/index.d.ts +31 -0
- package/dist/gs/go/token/index.js +82 -0
- package/dist/gs/go/token/index.js.map +1 -0
- package/dist/gs/internal/abi/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/readfile.js.map +1 -1
- package/dist/gs/io/fs/stat.js.map +1 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +2 -4
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/rawconn_js.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/tempfile.gs.js +66 -9
- package/dist/gs/os/tempfile.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +9 -9
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/match.js.map +1 -1
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +2 -2
- package/dist/gs/reflect/index.js +1 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +2 -1
- package/dist/gs/reflect/type.js +85 -14
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/sort/sort.gs.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/quote.gs.js.map +1 -1
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +1 -0
- package/dist/gs/sync/sync.js +12 -0
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/go.mod +2 -2
- package/gs/builtin/builtin.ts +27 -0
- package/gs/builtin/hostio.test.ts +177 -0
- package/gs/builtin/hostio.ts +171 -56
- package/gs/builtin/index.ts +1 -0
- package/gs/builtin/runtime-contract.test.ts +230 -0
- package/gs/builtin/type.ts +84 -1
- package/gs/crypto/rand/index.test.ts +32 -0
- package/gs/crypto/rand/index.ts +90 -0
- package/gs/crypto/rand/meta.json +5 -0
- package/gs/encoding/json/index.test.ts +65 -0
- package/gs/encoding/json/index.ts +186 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +23 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +3 -1
- package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/meta.json +3 -1
- package/gs/go/scanner/index.test.ts +50 -0
- package/gs/go/scanner/index.ts +157 -0
- package/gs/go/token/index.test.ts +21 -0
- package/gs/go/token/index.ts +120 -0
- package/gs/os/file_unix_js.test.ts +50 -0
- package/gs/os/meta.json +1 -2
- package/gs/os/tempfile.gs.test.ts +85 -0
- package/gs/os/tempfile.gs.ts +71 -11
- package/gs/os/types_js.gs.ts +9 -9
- package/gs/reflect/index.ts +1 -1
- package/gs/reflect/type.ts +106 -17
- package/gs/reflect/typefor.test.ts +75 -0
- package/gs/sync/sync.test.ts +24 -0
- package/gs/sync/sync.ts +12 -0
- package/package.json +13 -13
- package/compiler/analysis.go +0 -3475
- package/compiler/analysis_test.go +0 -338
- package/compiler/assignment.go +0 -580
- package/compiler/builtin_test.go +0 -92
- package/compiler/code-writer.go +0 -115
- package/compiler/compiler_test.go +0 -149
- package/compiler/composite-lit.go +0 -779
- package/compiler/config_test.go +0 -62
- package/compiler/constraint.go +0 -86
- package/compiler/decl.go +0 -801
- package/compiler/expr-call-async.go +0 -188
- package/compiler/expr-call-builtins.go +0 -208
- package/compiler/expr-call-helpers.go +0 -382
- package/compiler/expr-call-make.go +0 -318
- package/compiler/expr-call-type-conversion.go +0 -520
- package/compiler/expr-call.go +0 -413
- package/compiler/expr-selector.go +0 -343
- package/compiler/expr-star.go +0 -82
- package/compiler/expr-type.go +0 -442
- package/compiler/expr-value.go +0 -89
- package/compiler/expr.go +0 -773
- package/compiler/field.go +0 -183
- package/compiler/gs_dependencies_test.go +0 -298
- package/compiler/lit.go +0 -322
- package/compiler/output.go +0 -72
- package/compiler/primitive.go +0 -149
- package/compiler/protobuf.go +0 -697
- package/compiler/sanitize.go +0 -100
- package/compiler/spec-struct.go +0 -995
- package/compiler/spec-value.go +0 -540
- package/compiler/spec.go +0 -725
- package/compiler/stmt-assign.go +0 -664
- package/compiler/stmt-for.go +0 -266
- package/compiler/stmt-range.go +0 -475
- package/compiler/stmt-select.go +0 -262
- package/compiler/stmt-type-switch.go +0 -147
- package/compiler/stmt.go +0 -1308
- package/compiler/type-assert.go +0 -386
- package/compiler/type-info.go +0 -156
- package/compiler/type-utils.go +0 -207
- package/compiler/type.go +0 -892
|
@@ -1,382 +0,0 @@
|
|
|
1
|
-
package compiler
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"go/ast"
|
|
5
|
-
"go/types"
|
|
6
|
-
|
|
7
|
-
"github.com/pkg/errors"
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
// writeByteSliceCreation handles the creation of []byte slices with proper Uint8Array handling
|
|
11
|
-
func (c *GoToTSCompiler) writeByteSliceCreation(lengthArg, capacityArg any) error {
|
|
12
|
-
return c.writeSliceCreationForType(lengthArg, capacityArg, true)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// writeSliceCreationForType handles slice creation with special handling for byte slices
|
|
16
|
-
func (c *GoToTSCompiler) writeSliceCreationForType(lengthArg, capacityArg any, isByteSlice bool) error {
|
|
17
|
-
hasCapacity := capacityArg != nil
|
|
18
|
-
|
|
19
|
-
if isByteSlice && !hasCapacity {
|
|
20
|
-
// make([]byte, len) - capacity equals length, use Uint8Array
|
|
21
|
-
c.tsw.WriteLiterally("new Uint8Array(")
|
|
22
|
-
if err := c.writeExprOrDefault(lengthArg, "0"); err != nil {
|
|
23
|
-
return err
|
|
24
|
-
}
|
|
25
|
-
c.tsw.WriteLiterally(")")
|
|
26
|
-
return nil
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Use $.makeSlice for all other cases
|
|
30
|
-
if isByteSlice {
|
|
31
|
-
c.tsw.WriteLiterally("$.makeSlice<number>(")
|
|
32
|
-
} else {
|
|
33
|
-
return errors.New("writeSliceCreationForType called for non-byte slice without element type")
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if err := c.writeExprOrDefault(lengthArg, "0"); err != nil {
|
|
37
|
-
return err
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if hasCapacity {
|
|
41
|
-
c.tsw.WriteLiterally(", ")
|
|
42
|
-
if err := c.writeExprOrDefault(capacityArg, "0"); err != nil {
|
|
43
|
-
return err
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if isByteSlice {
|
|
48
|
-
c.tsw.WriteLiterally(", 'byte')")
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return nil
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// writeGenericSliceCreation handles the creation of generic slices with proper type hints
|
|
55
|
-
func (c *GoToTSCompiler) writeGenericSliceCreation(elemType types.Type, lengthArg, capacityArg any) error {
|
|
56
|
-
hasCapacity := capacityArg != nil
|
|
57
|
-
|
|
58
|
-
c.tsw.WriteLiterally("$.makeSlice<")
|
|
59
|
-
c.WriteGoType(elemType, GoTypeContextGeneral)
|
|
60
|
-
c.tsw.WriteLiterally(">(")
|
|
61
|
-
|
|
62
|
-
if err := c.writeExprOrDefault(lengthArg, "0"); err != nil {
|
|
63
|
-
return err
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if hasCapacity {
|
|
67
|
-
c.tsw.WriteLiterally(", ")
|
|
68
|
-
if err := c.writeExprOrDefault(capacityArg, "0"); err != nil {
|
|
69
|
-
return err
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Add type hint for proper zero value initialization
|
|
74
|
-
c.writeSliceTypeHint(elemType, hasCapacity)
|
|
75
|
-
c.tsw.WriteLiterally(")")
|
|
76
|
-
return nil
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// writeSliceTypeHint writes the type hint parameter for makeSlice calls
|
|
80
|
-
func (c *GoToTSCompiler) writeSliceTypeHint(elemType types.Type, hasCapacity bool) {
|
|
81
|
-
typeHint := c.getTypeHintForSliceElement(elemType)
|
|
82
|
-
if typeHint != "" {
|
|
83
|
-
if !hasCapacity {
|
|
84
|
-
c.tsw.WriteLiterally(", undefined")
|
|
85
|
-
}
|
|
86
|
-
c.tsw.WriteLiterally(", '")
|
|
87
|
-
c.tsw.WriteLiterally(typeHint)
|
|
88
|
-
c.tsw.WriteLiterally("'")
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// writeExprOrDefault writes an expression if it's not nil, otherwise writes a default value
|
|
93
|
-
func (c *GoToTSCompiler) writeExprOrDefault(expr any, defaultValue string) error {
|
|
94
|
-
if expr == nil {
|
|
95
|
-
c.tsw.WriteLiterally(defaultValue)
|
|
96
|
-
return nil
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
switch e := expr.(type) {
|
|
100
|
-
case string:
|
|
101
|
-
c.tsw.WriteLiterally(e)
|
|
102
|
-
return nil
|
|
103
|
-
case ast.Expr:
|
|
104
|
-
// If it's an ast.Expr, call WriteValueExpr directly
|
|
105
|
-
return c.WriteValueExpr(e)
|
|
106
|
-
default:
|
|
107
|
-
// If we can't handle the type, return an error
|
|
108
|
-
return errors.Errorf("unsupported expression type in writeExprOrDefault: %T", e)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// writeReflectTypeFor handles reflect.TypeFor[T]() calls by generating appropriate TypeScript
|
|
113
|
-
func (c *GoToTSCompiler) writeReflectTypeFor(exp *ast.CallExpr, selectorExpr *ast.SelectorExpr) (handled bool, err error) {
|
|
114
|
-
// Check if this is reflect.TypeFor
|
|
115
|
-
if selectorExpr.Sel.Name != "TypeFor" {
|
|
116
|
-
return false, nil
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Check if X is an identifier referring to the reflect package
|
|
120
|
-
xIdent, ok := selectorExpr.X.(*ast.Ident)
|
|
121
|
-
if !ok {
|
|
122
|
-
return false, nil
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
obj := c.objectOfIdent(xIdent)
|
|
126
|
-
if obj == nil {
|
|
127
|
-
return false, nil
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
pkgName, ok := obj.(*types.PkgName)
|
|
131
|
-
if !ok || pkgName.Imported().Path() != "reflect" {
|
|
132
|
-
return false, nil
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// DEBUG: We found reflect.TypeFor
|
|
136
|
-
// fmt.Printf("DEBUG: Found reflect.TypeFor call\n")
|
|
137
|
-
|
|
138
|
-
// This is reflect.TypeFor - now get the type argument
|
|
139
|
-
if c.pkg.TypesInfo.Instances == nil {
|
|
140
|
-
return false, errors.New("reflect.TypeFor called but no type instances available")
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
instance, hasInstance := c.pkg.TypesInfo.Instances[selectorExpr.Sel]
|
|
144
|
-
if !hasInstance || instance.TypeArgs == nil || instance.TypeArgs.Len() == 0 {
|
|
145
|
-
return false, errors.New("reflect.TypeFor called without type arguments")
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Get the first type argument
|
|
149
|
-
typeArg := instance.TypeArgs.At(0)
|
|
150
|
-
// fmt.Printf("DEBUG: Type argument: %v\n", typeArg)
|
|
151
|
-
|
|
152
|
-
if named, ok := typeArg.(*types.Named); ok {
|
|
153
|
-
if _, isInterface := named.Underlying().(*types.Interface); isInterface {
|
|
154
|
-
typeName := qualifiedTypeName(named)
|
|
155
|
-
c.tsw.WriteLiterally("reflect.getInterfaceLiteralTypeByName(\"" + typeName + "\")")
|
|
156
|
-
return true, nil
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Generate TypeScript code to create a Type for this type
|
|
161
|
-
if err := c.writeTypeForTypeArg(typeArg); err != nil {
|
|
162
|
-
return true, err
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return true, nil
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// writeReflectTypeAssert handles reflect.TypeAssert[T](v) calls.
|
|
169
|
-
func (c *GoToTSCompiler) writeReflectTypeAssert(exp *ast.CallExpr, selectorExpr *ast.SelectorExpr) (handled bool, err error) {
|
|
170
|
-
if selectorExpr.Sel.Name != "TypeAssert" {
|
|
171
|
-
return false, nil
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
xIdent, ok := selectorExpr.X.(*ast.Ident)
|
|
175
|
-
if !ok {
|
|
176
|
-
return false, nil
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
obj := c.objectOfIdent(xIdent)
|
|
180
|
-
if obj == nil {
|
|
181
|
-
return false, nil
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
pkgName, ok := obj.(*types.PkgName)
|
|
185
|
-
if !ok || pkgName.Imported().Path() != "reflect" {
|
|
186
|
-
return false, nil
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if len(exp.Args) != 1 {
|
|
190
|
-
return false, errors.New("reflect.TypeAssert called with unexpected argument count")
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if c.pkg.TypesInfo.Instances == nil {
|
|
194
|
-
return false, errors.New("reflect.TypeAssert called but no type instances available")
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
instance, hasInstance := c.pkg.TypesInfo.Instances[selectorExpr.Sel]
|
|
198
|
-
if !hasInstance || instance.TypeArgs == nil || instance.TypeArgs.Len() == 0 {
|
|
199
|
-
return false, errors.New("reflect.TypeAssert called without type arguments")
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
typeArg := instance.TypeArgs.At(0)
|
|
203
|
-
|
|
204
|
-
c.tsw.WriteLiterally("$.typeAssertTuple<")
|
|
205
|
-
c.WriteGoType(typeArg, GoTypeContextGeneral)
|
|
206
|
-
c.tsw.WriteLiterally(">(")
|
|
207
|
-
if err := c.WriteValueExpr(exp.Args[0]); err != nil {
|
|
208
|
-
return true, err
|
|
209
|
-
}
|
|
210
|
-
c.tsw.WriteLiterally(".Interface(), ")
|
|
211
|
-
c.writeTypeInfoObject(typeArg)
|
|
212
|
-
c.tsw.WriteLiterally(")")
|
|
213
|
-
return true, nil
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// writeTypeForTypeArg generates TypeScript code to create a reflect.Type for the given Go type
|
|
217
|
-
func (c *GoToTSCompiler) writeTypeForTypeArg(t types.Type) error {
|
|
218
|
-
// Handle basic types
|
|
219
|
-
switch underlying := t.Underlying().(type) {
|
|
220
|
-
case *types.Basic:
|
|
221
|
-
return c.writeBasicTypeFor(underlying)
|
|
222
|
-
case *types.Named:
|
|
223
|
-
// For named types, use TypeOf with a zero value
|
|
224
|
-
return c.writeNamedTypeFor(t)
|
|
225
|
-
case *types.Pointer:
|
|
226
|
-
// For pointer types, use PointerTo
|
|
227
|
-
c.tsw.WriteLiterally("reflect.PointerTo(")
|
|
228
|
-
if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
|
|
229
|
-
return err
|
|
230
|
-
}
|
|
231
|
-
c.tsw.WriteLiterally(")")
|
|
232
|
-
return nil
|
|
233
|
-
case *types.Slice:
|
|
234
|
-
c.tsw.WriteLiterally("reflect.SliceOf(")
|
|
235
|
-
if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
|
|
236
|
-
return err
|
|
237
|
-
}
|
|
238
|
-
c.tsw.WriteLiterally(")")
|
|
239
|
-
return nil
|
|
240
|
-
case *types.Array:
|
|
241
|
-
c.tsw.WriteLiterally("reflect.ArrayOf(")
|
|
242
|
-
c.tsw.WriteLiterallyf("%d, ", underlying.Len())
|
|
243
|
-
if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
|
|
244
|
-
return err
|
|
245
|
-
}
|
|
246
|
-
c.tsw.WriteLiterally(")")
|
|
247
|
-
return nil
|
|
248
|
-
case *types.Map:
|
|
249
|
-
c.tsw.WriteLiterally("reflect.MapOf(")
|
|
250
|
-
if err := c.writeTypeForTypeArg(underlying.Key()); err != nil {
|
|
251
|
-
return err
|
|
252
|
-
}
|
|
253
|
-
c.tsw.WriteLiterally(", ")
|
|
254
|
-
if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
|
|
255
|
-
return err
|
|
256
|
-
}
|
|
257
|
-
c.tsw.WriteLiterally(")")
|
|
258
|
-
return nil
|
|
259
|
-
case *types.Chan:
|
|
260
|
-
c.tsw.WriteLiterally("reflect.ChanOf(")
|
|
261
|
-
switch underlying.Dir() {
|
|
262
|
-
case types.RecvOnly:
|
|
263
|
-
c.tsw.WriteLiterally("reflect.RecvDir")
|
|
264
|
-
case types.SendOnly:
|
|
265
|
-
c.tsw.WriteLiterally("reflect.SendDir")
|
|
266
|
-
default:
|
|
267
|
-
c.tsw.WriteLiterally("reflect.BothDir")
|
|
268
|
-
}
|
|
269
|
-
c.tsw.WriteLiterally(", ")
|
|
270
|
-
if err := c.writeTypeForTypeArg(underlying.Elem()); err != nil {
|
|
271
|
-
return err
|
|
272
|
-
}
|
|
273
|
-
c.tsw.WriteLiterally(")")
|
|
274
|
-
return nil
|
|
275
|
-
case *types.Struct:
|
|
276
|
-
// For struct types, use TypeOf with zero value
|
|
277
|
-
return c.writeNamedTypeFor(t)
|
|
278
|
-
case *types.Interface:
|
|
279
|
-
// For interface types, use TypeOf with null
|
|
280
|
-
return c.writeNamedTypeFor(t)
|
|
281
|
-
default:
|
|
282
|
-
return errors.Errorf("unsupported type for reflect.TypeFor: %T", underlying)
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// writeBasicTypeFor generates code for basic types
|
|
287
|
-
func (c *GoToTSCompiler) writeBasicTypeFor(basic *types.Basic) error {
|
|
288
|
-
// Map basic types to their reflect constructors or TypeOf calls
|
|
289
|
-
// Note: We don't pass type parameters to TypeOf - it infers from the value
|
|
290
|
-
switch basic.Kind() {
|
|
291
|
-
case types.Bool:
|
|
292
|
-
c.tsw.WriteLiterally("reflect.TypeOf(false)")
|
|
293
|
-
case types.Int:
|
|
294
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
295
|
-
case types.Int8:
|
|
296
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
297
|
-
case types.Int16:
|
|
298
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
299
|
-
case types.Int32:
|
|
300
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
301
|
-
case types.Int64:
|
|
302
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0n)")
|
|
303
|
-
case types.Uint:
|
|
304
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
305
|
-
case types.Uint8:
|
|
306
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
307
|
-
case types.Uint16:
|
|
308
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
309
|
-
case types.Uint32:
|
|
310
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
311
|
-
case types.Uint64:
|
|
312
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0n)")
|
|
313
|
-
case types.Uintptr:
|
|
314
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
315
|
-
case types.Float32:
|
|
316
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
317
|
-
case types.Float64:
|
|
318
|
-
c.tsw.WriteLiterally("reflect.TypeOf(0)")
|
|
319
|
-
case types.Complex64:
|
|
320
|
-
c.tsw.WriteLiterally("reflect.TypeOf([0, 0])")
|
|
321
|
-
case types.Complex128:
|
|
322
|
-
c.tsw.WriteLiterally("reflect.TypeOf([0, 0])")
|
|
323
|
-
case types.String:
|
|
324
|
-
c.tsw.WriteLiterally("reflect.TypeOf(\"\")")
|
|
325
|
-
case types.UnsafePointer:
|
|
326
|
-
c.tsw.WriteLiterally("reflect.TypeOf(null)")
|
|
327
|
-
default:
|
|
328
|
-
return errors.Errorf("unsupported basic type for reflect.TypeFor: %v", basic)
|
|
329
|
-
}
|
|
330
|
-
return nil
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// writeNamedTypeFor generates code for named types (structs, interfaces, etc.)
|
|
334
|
-
func (c *GoToTSCompiler) writeNamedTypeFor(t types.Type) error {
|
|
335
|
-
// For interface types, we need special handling since null doesn't carry type info
|
|
336
|
-
if _, ok := t.Underlying().(*types.Interface); ok {
|
|
337
|
-
if named, ok := t.(*types.Named); ok {
|
|
338
|
-
obj := named.Obj()
|
|
339
|
-
pkgPath := ""
|
|
340
|
-
if pkg := obj.Pkg(); pkg != nil {
|
|
341
|
-
if pkg.Name() == "main" {
|
|
342
|
-
pkgPath = "main."
|
|
343
|
-
} else if pkg.Path() != "" {
|
|
344
|
-
pkgPath = pkg.Path() + "."
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
typeName := pkgPath + obj.Name()
|
|
348
|
-
c.tsw.WriteLiterally("reflect.getInterfaceTypeByName(\"" + typeName + "\")")
|
|
349
|
-
return nil
|
|
350
|
-
}
|
|
351
|
-
// For anonymous interfaces, use TypeOf(null)
|
|
352
|
-
c.tsw.WriteLiterally("reflect.TypeOf(null)")
|
|
353
|
-
return nil
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// For named types, we need to create a zero value and call TypeOf
|
|
357
|
-
// Note: We don't pass a type parameter to TypeOf - it infers the type from the value
|
|
358
|
-
c.tsw.WriteLiterally("reflect.TypeOf(")
|
|
359
|
-
|
|
360
|
-
// Generate a zero value for this type
|
|
361
|
-
switch underlying := t.Underlying().(type) {
|
|
362
|
-
case *types.Struct:
|
|
363
|
-
// For struct types: new MyStruct()
|
|
364
|
-
// Check if this is a named type
|
|
365
|
-
if _, ok := t.(*types.Named); ok {
|
|
366
|
-
c.tsw.WriteLiterally("new ")
|
|
367
|
-
c.WriteGoType(t, GoTypeContextGeneral)
|
|
368
|
-
c.tsw.WriteLiterally("()")
|
|
369
|
-
} else {
|
|
370
|
-
// Anonymous struct
|
|
371
|
-
c.tsw.WriteLiterally("{}")
|
|
372
|
-
}
|
|
373
|
-
case *types.Basic:
|
|
374
|
-
// For basic types wrapped in named types
|
|
375
|
-
return c.writeBasicTypeFor(underlying)
|
|
376
|
-
default:
|
|
377
|
-
return errors.Errorf("unsupported named type underlying for reflect.TypeFor: %T", underlying)
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
c.tsw.WriteLiterally(")")
|
|
381
|
-
return nil
|
|
382
|
-
}
|
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
package compiler
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"fmt"
|
|
5
|
-
"go/ast"
|
|
6
|
-
"go/types"
|
|
7
|
-
|
|
8
|
-
"github.com/pkg/errors"
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
// getTypeHintForSliceElement returns the appropriate type hint for makeSlice based on the Go element type
|
|
12
|
-
func (c *GoToTSCompiler) getTypeHintForSliceElement(elemType types.Type) string {
|
|
13
|
-
if basicType, isBasic := elemType.(*types.Basic); isBasic {
|
|
14
|
-
switch basicType.Kind() {
|
|
15
|
-
case types.Int, types.Int8, types.Int16, types.Int32, types.Int64,
|
|
16
|
-
types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64,
|
|
17
|
-
types.Float32, types.Float64, types.Complex64, types.Complex128:
|
|
18
|
-
return "number"
|
|
19
|
-
case types.Bool:
|
|
20
|
-
return "boolean"
|
|
21
|
-
case types.String:
|
|
22
|
-
return "string"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
// For other types (structs, interfaces, pointers, etc.), don't provide a hint
|
|
26
|
-
// This will use the default null initialization which is appropriate for object types
|
|
27
|
-
return ""
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// writeMakeChannel writes the TypeScript code for creating a channel with $.makeChannel
|
|
31
|
-
// It handles buffer size, zero value, and direction parameters
|
|
32
|
-
func (c *GoToTSCompiler) writeMakeChannel(chanType *types.Chan, bufferArg ast.Expr) error {
|
|
33
|
-
c.tsw.WriteLiterally("$.makeChannel<")
|
|
34
|
-
c.WriteGoType(chanType.Elem(), GoTypeContextGeneral)
|
|
35
|
-
c.tsw.WriteLiterally(">(")
|
|
36
|
-
|
|
37
|
-
// If buffer size is provided, add it
|
|
38
|
-
if bufferArg != nil {
|
|
39
|
-
if err := c.WriteValueExpr(bufferArg); err != nil {
|
|
40
|
-
return fmt.Errorf("failed to write buffer size in makeChannel: %w", err)
|
|
41
|
-
}
|
|
42
|
-
} else {
|
|
43
|
-
// Default to 0 (unbuffered channel)
|
|
44
|
-
c.tsw.WriteLiterally("0")
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
c.tsw.WriteLiterally(", ") // Add comma for zero value argument
|
|
48
|
-
|
|
49
|
-
// Write the zero value for the channel's element type
|
|
50
|
-
if chanType.Elem().String() == "struct{}" {
|
|
51
|
-
c.tsw.WriteLiterally("{}")
|
|
52
|
-
} else {
|
|
53
|
-
c.WriteZeroValueForType(chanType.Elem())
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Add direction parameter
|
|
57
|
-
c.tsw.WriteLiterally(", ")
|
|
58
|
-
|
|
59
|
-
// Determine channel direction
|
|
60
|
-
switch chanType.Dir() {
|
|
61
|
-
case types.SendRecv:
|
|
62
|
-
c.tsw.WriteLiterally("'both'")
|
|
63
|
-
case types.SendOnly:
|
|
64
|
-
c.tsw.WriteLiterally("'send'")
|
|
65
|
-
case types.RecvOnly:
|
|
66
|
-
c.tsw.WriteLiterally("'receive'")
|
|
67
|
-
default:
|
|
68
|
-
c.tsw.WriteLiterally("'both'") // Default to bidirectional
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
c.tsw.WriteLiterally(")")
|
|
72
|
-
return nil
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// writeMakeSlice writes the TypeScript code for creating a slice
|
|
76
|
-
// It handles []byte special case and generic slice creation
|
|
77
|
-
func (c *GoToTSCompiler) writeMakeSlice(sliceType *types.Slice, exp *ast.CallExpr) error {
|
|
78
|
-
goElemType := sliceType.Elem()
|
|
79
|
-
|
|
80
|
-
// Check if it's []byte
|
|
81
|
-
if c.isByteSliceType(sliceType) {
|
|
82
|
-
var lengthArg, capacityArg any
|
|
83
|
-
if len(exp.Args) >= 2 {
|
|
84
|
-
lengthArg = exp.Args[1]
|
|
85
|
-
}
|
|
86
|
-
if len(exp.Args) == 3 {
|
|
87
|
-
capacityArg = exp.Args[2]
|
|
88
|
-
}
|
|
89
|
-
return c.writeByteSliceCreation(lengthArg, capacityArg)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Handle other slice types
|
|
93
|
-
var lengthArg, capacityArg any
|
|
94
|
-
if len(exp.Args) >= 2 {
|
|
95
|
-
lengthArg = exp.Args[1]
|
|
96
|
-
}
|
|
97
|
-
if len(exp.Args) == 3 {
|
|
98
|
-
capacityArg = exp.Args[2]
|
|
99
|
-
} else if len(exp.Args) > 3 {
|
|
100
|
-
return errors.New("makeSlice expects 2 or 3 arguments")
|
|
101
|
-
}
|
|
102
|
-
return c.writeGenericSliceCreation(goElemType, lengthArg, capacityArg)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// WriteCallExprMake handles make() function calls and translates them to TypeScript.
|
|
106
|
-
// It handles channel, map, and slice creation with different type patterns including:
|
|
107
|
-
// - Channel creation with different directions
|
|
108
|
-
// - Map creation for various type patterns
|
|
109
|
-
// - Slice creation with special handling for []byte, generic types, named types, instantiated generics, and selector expressions
|
|
110
|
-
func (c *GoToTSCompiler) WriteCallExprMake(exp *ast.CallExpr) error {
|
|
111
|
-
// First check if we have a channel type
|
|
112
|
-
if typ := c.pkg.TypesInfo.TypeOf(exp.Args[0]); typ != nil {
|
|
113
|
-
if chanType, ok := typ.Underlying().(*types.Chan); ok {
|
|
114
|
-
// Handle channel creation: make(chan T, bufferSize) or make(chan T)
|
|
115
|
-
var bufferArg ast.Expr
|
|
116
|
-
if len(exp.Args) >= 2 {
|
|
117
|
-
bufferArg = exp.Args[1]
|
|
118
|
-
}
|
|
119
|
-
return c.writeMakeChannel(chanType, bufferArg)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// Handle make for slices: make([]T, len, cap) or make([]T, len)
|
|
123
|
-
if len(exp.Args) >= 1 {
|
|
124
|
-
// Handle map creation: make(map[K]V)
|
|
125
|
-
if mapType, ok := exp.Args[0].(*ast.MapType); ok {
|
|
126
|
-
c.tsw.WriteLiterally("$.makeMap<")
|
|
127
|
-
c.WriteTypeExpr(mapType.Key) // Write the key type
|
|
128
|
-
c.tsw.WriteLiterally(", ")
|
|
129
|
-
c.WriteTypeExpr(mapType.Value) // Write the value type
|
|
130
|
-
c.tsw.WriteLiterally(">()")
|
|
131
|
-
return nil // Handled make for map
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Handle slice creation
|
|
135
|
-
if _, ok := exp.Args[0].(*ast.ArrayType); ok {
|
|
136
|
-
// Get the slice type information
|
|
137
|
-
sliceType := c.pkg.TypesInfo.TypeOf(exp.Args[0])
|
|
138
|
-
if sliceType == nil {
|
|
139
|
-
return errors.New("could not get type information for slice in make call")
|
|
140
|
-
}
|
|
141
|
-
goUnderlyingType, ok := sliceType.Underlying().(*types.Slice)
|
|
142
|
-
if !ok {
|
|
143
|
-
return errors.New("expected slice type for make call")
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Check if the element type is a generic type parameter
|
|
147
|
-
if _, isTypeParam := goUnderlyingType.Elem().(*types.TypeParam); isTypeParam {
|
|
148
|
-
// This is make([]E, n) where E is a type parameter
|
|
149
|
-
c.tsw.WriteLiterally("$.makeSlice<")
|
|
150
|
-
c.WriteGoType(goUnderlyingType.Elem(), GoTypeContextGeneral) // Write the element type parameter
|
|
151
|
-
c.tsw.WriteLiterally(">(")
|
|
152
|
-
|
|
153
|
-
if len(exp.Args) >= 2 {
|
|
154
|
-
if err := c.WriteValueExpr(exp.Args[1]); err != nil { // Length
|
|
155
|
-
return err
|
|
156
|
-
}
|
|
157
|
-
if len(exp.Args) == 3 {
|
|
158
|
-
c.tsw.WriteLiterally(", ")
|
|
159
|
-
if err := c.WriteValueExpr(exp.Args[2]); err != nil { // Capacity
|
|
160
|
-
return err
|
|
161
|
-
}
|
|
162
|
-
} else if len(exp.Args) > 3 {
|
|
163
|
-
return errors.New("makeSlice expects 2 or 3 arguments")
|
|
164
|
-
}
|
|
165
|
-
} else {
|
|
166
|
-
// If no length is provided, default to 0
|
|
167
|
-
c.tsw.WriteLiterally("0")
|
|
168
|
-
}
|
|
169
|
-
c.tsw.WriteLiterally(")")
|
|
170
|
-
return nil // Handled make for []E where E is type parameter
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return c.writeMakeSlice(goUnderlyingType, exp)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Handle generic type parameter make calls: make(S, len, cap) where S ~[]E
|
|
177
|
-
if ident, ok := exp.Args[0].(*ast.Ident); ok {
|
|
178
|
-
// Check if this identifier refers to a type parameter
|
|
179
|
-
if obj := c.pkg.TypesInfo.Uses[ident]; obj != nil {
|
|
180
|
-
if typeName, isTypeName := obj.(*types.TypeName); isTypeName {
|
|
181
|
-
if typeParam, isTypeParam := typeName.Type().(*types.TypeParam); isTypeParam {
|
|
182
|
-
// Check if the type parameter is constrained to slice types
|
|
183
|
-
constraint := typeParam.Constraint()
|
|
184
|
-
if constraint != nil {
|
|
185
|
-
underlying := constraint.Underlying()
|
|
186
|
-
if iface, isInterface := underlying.(*types.Interface); isInterface {
|
|
187
|
-
// Check if the constraint includes slice types
|
|
188
|
-
// For constraints like ~[]E, we need to look at the type terms
|
|
189
|
-
if hasSliceConstraint(iface) {
|
|
190
|
-
// This is a generic slice type parameter
|
|
191
|
-
// We need to determine the element type from the constraint
|
|
192
|
-
elemType := getSliceElementTypeFromConstraint(iface)
|
|
193
|
-
if elemType != nil {
|
|
194
|
-
// Check if it's make(S, ...) where S constrains to []byte
|
|
195
|
-
if c.isByteSliceType(types.NewSlice(elemType)) {
|
|
196
|
-
var lengthArg, capacityArg any
|
|
197
|
-
if len(exp.Args) >= 2 {
|
|
198
|
-
lengthArg = exp.Args[1]
|
|
199
|
-
}
|
|
200
|
-
if len(exp.Args) == 3 {
|
|
201
|
-
capacityArg = exp.Args[2]
|
|
202
|
-
}
|
|
203
|
-
return c.writeByteSliceCreation(lengthArg, capacityArg)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
var lengthArg, capacityArg any
|
|
207
|
-
if len(exp.Args) >= 2 {
|
|
208
|
-
lengthArg = exp.Args[1]
|
|
209
|
-
}
|
|
210
|
-
if len(exp.Args) == 3 {
|
|
211
|
-
capacityArg = exp.Args[2]
|
|
212
|
-
} else if len(exp.Args) > 3 {
|
|
213
|
-
return errors.New("makeSlice expects 2 or 3 arguments")
|
|
214
|
-
}
|
|
215
|
-
return c.writeGenericSliceCreation(elemType, lengthArg, capacityArg)
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
} else {
|
|
221
|
-
// Handle named types with slice underlying types: make(NamedSliceType, len, cap)
|
|
222
|
-
namedType := typeName.Type()
|
|
223
|
-
if sliceType, isSlice := namedType.Underlying().(*types.Slice); isSlice {
|
|
224
|
-
return c.writeMakeSlice(sliceType, exp)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Handle named types with map underlying types: make(NamedMapType)
|
|
228
|
-
if mapType, isMap := namedType.Underlying().(*types.Map); isMap {
|
|
229
|
-
c.tsw.WriteLiterally("$.makeMap<")
|
|
230
|
-
c.WriteGoType(mapType.Key(), GoTypeContextGeneral) // Write the key type
|
|
231
|
-
c.tsw.WriteLiterally(", ")
|
|
232
|
-
c.WriteGoType(mapType.Elem(), GoTypeContextGeneral) // Write the value type
|
|
233
|
-
c.tsw.WriteLiterally(">()")
|
|
234
|
-
return nil // Handled make for named map type
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Handle named types with channel underlying types: make(NamedChannelType, bufferSize)
|
|
238
|
-
if chanType, isChan := namedType.Underlying().(*types.Chan); isChan {
|
|
239
|
-
var bufferArg ast.Expr
|
|
240
|
-
if len(exp.Args) >= 2 {
|
|
241
|
-
bufferArg = exp.Args[1]
|
|
242
|
-
}
|
|
243
|
-
return c.writeMakeChannel(chanType, bufferArg)
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
// Handle instantiated generic types: make(GenericType[TypeArg], ...)
|
|
251
|
-
// This handles cases like: make(Ints[int64]) where Ints[T] is a generic type
|
|
252
|
-
if indexExpr, ok := exp.Args[0].(*ast.IndexExpr); ok {
|
|
253
|
-
// Get the type information for the instantiated generic type
|
|
254
|
-
if typ := c.pkg.TypesInfo.TypeOf(indexExpr); typ != nil {
|
|
255
|
-
// Check the underlying type of the instantiated generic type
|
|
256
|
-
underlying := typ.Underlying()
|
|
257
|
-
|
|
258
|
-
// Handle instantiated generic map types: make(GenericMap[K, V])
|
|
259
|
-
if mapType, isMap := underlying.(*types.Map); isMap {
|
|
260
|
-
c.tsw.WriteLiterally("$.makeMap<")
|
|
261
|
-
c.WriteGoType(mapType.Key(), GoTypeContextGeneral) // Write the key type
|
|
262
|
-
c.tsw.WriteLiterally(", ")
|
|
263
|
-
c.WriteGoType(mapType.Elem(), GoTypeContextGeneral) // Write the value type
|
|
264
|
-
c.tsw.WriteLiterally(">()")
|
|
265
|
-
return nil // Handled make for instantiated generic map type
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Handle instantiated generic slice types: make(GenericSlice[T], len, cap)
|
|
269
|
-
if sliceType, isSlice := underlying.(*types.Slice); isSlice {
|
|
270
|
-
return c.writeMakeSlice(sliceType, exp)
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Handle instantiated generic channel types: make(GenericChannel[T], bufferSize)
|
|
274
|
-
if chanType, isChan := underlying.(*types.Chan); isChan {
|
|
275
|
-
var bufferArg ast.Expr
|
|
276
|
-
if len(exp.Args) >= 2 {
|
|
277
|
-
bufferArg = exp.Args[1]
|
|
278
|
-
}
|
|
279
|
-
return c.writeMakeChannel(chanType, bufferArg)
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
// Handle selector expressions: make(pkg.TypeName, ...)
|
|
284
|
-
// This handles cases like: make(fstest.MapFS) where fstest.MapFS is map[string]*MapFile
|
|
285
|
-
if selectorExpr, ok := exp.Args[0].(*ast.SelectorExpr); ok {
|
|
286
|
-
// Get the type information for the selector expression
|
|
287
|
-
if typ := c.pkg.TypesInfo.TypeOf(selectorExpr); typ != nil {
|
|
288
|
-
// Check the underlying type of the selector expression
|
|
289
|
-
underlying := typ.Underlying()
|
|
290
|
-
|
|
291
|
-
// Handle selector expression map types: make(pkg.MapType)
|
|
292
|
-
if mapType, isMap := underlying.(*types.Map); isMap {
|
|
293
|
-
c.tsw.WriteLiterally("$.makeMap<")
|
|
294
|
-
c.WriteGoType(mapType.Key(), GoTypeContextGeneral) // Write the key type
|
|
295
|
-
c.tsw.WriteLiterally(", ")
|
|
296
|
-
c.WriteGoType(mapType.Elem(), GoTypeContextGeneral) // Write the value type
|
|
297
|
-
c.tsw.WriteLiterally(">()")
|
|
298
|
-
return nil // Handled make for selector expression map type
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// Handle selector expression slice types: make(pkg.SliceType, len, cap)
|
|
302
|
-
if sliceType, isSlice := underlying.(*types.Slice); isSlice {
|
|
303
|
-
return c.writeMakeSlice(sliceType, exp)
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Handle selector expression channel types: make(pkg.ChannelType, bufferSize)
|
|
307
|
-
if chanType, isChan := underlying.(*types.Chan); isChan {
|
|
308
|
-
var bufferArg ast.Expr
|
|
309
|
-
if len(exp.Args) >= 2 {
|
|
310
|
-
bufferArg = exp.Args[1]
|
|
311
|
-
}
|
|
312
|
-
return c.writeMakeChannel(chanType, bufferArg)
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
// Fallthrough for unhandled make calls (e.g., channels)
|
|
317
|
-
return errors.New("unhandled make call")
|
|
318
|
-
}
|