goscript 0.0.22 → 0.0.24
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 +1 -1
- package/cmd/goscript/cmd_compile.go +3 -3
- package/compiler/analysis.go +302 -182
- package/compiler/analysis_test.go +220 -0
- package/compiler/assignment.go +42 -43
- package/compiler/builtin_test.go +102 -0
- package/compiler/compiler.go +117 -29
- package/compiler/compiler_test.go +36 -8
- package/compiler/composite-lit.go +133 -53
- package/compiler/config.go +7 -3
- package/compiler/config_test.go +6 -33
- package/compiler/decl.go +36 -0
- package/compiler/expr-call.go +116 -60
- package/compiler/expr-selector.go +88 -43
- package/compiler/expr-star.go +57 -65
- package/compiler/expr-type.go +132 -5
- package/compiler/expr-value.go +8 -38
- package/compiler/expr.go +326 -30
- package/compiler/field.go +3 -3
- package/compiler/lit.go +34 -2
- package/compiler/primitive.go +19 -12
- package/compiler/spec-struct.go +140 -9
- package/compiler/spec-value.go +119 -41
- package/compiler/spec.go +21 -6
- package/compiler/stmt-assign.go +65 -3
- package/compiler/stmt-for.go +11 -0
- package/compiler/stmt-range.go +119 -11
- package/compiler/stmt-select.go +211 -0
- package/compiler/stmt-type-switch.go +147 -0
- package/compiler/stmt.go +175 -238
- package/compiler/type-assert.go +125 -379
- package/compiler/type.go +216 -129
- package/dist/gs/builtin/builtin.js +37 -0
- package/dist/gs/builtin/builtin.js.map +1 -0
- package/dist/gs/builtin/channel.js +471 -0
- package/dist/gs/builtin/channel.js.map +1 -0
- package/dist/gs/builtin/defer.js +54 -0
- package/dist/gs/builtin/defer.js.map +1 -0
- package/dist/gs/builtin/io.js +15 -0
- package/dist/gs/builtin/io.js.map +1 -0
- package/dist/gs/builtin/map.js +44 -0
- package/dist/gs/builtin/map.js.map +1 -0
- package/dist/gs/builtin/slice.js +799 -0
- package/dist/gs/builtin/slice.js.map +1 -0
- package/dist/gs/builtin/type.js +745 -0
- package/dist/gs/builtin/type.js.map +1 -0
- package/dist/gs/builtin/varRef.js +14 -0
- package/dist/gs/builtin/varRef.js.map +1 -0
- package/dist/gs/context/context.js +55 -0
- package/dist/gs/context/context.js.map +1 -0
- package/dist/gs/context/index.js +2 -0
- package/dist/gs/context/index.js.map +1 -0
- package/dist/gs/runtime/index.js +2 -0
- package/dist/gs/runtime/index.js.map +1 -0
- package/dist/gs/runtime/runtime.js +158 -0
- package/dist/gs/runtime/runtime.js.map +1 -0
- package/dist/gs/time/index.js +2 -0
- package/dist/gs/time/index.js.map +1 -0
- package/dist/gs/time/time.js +115 -0
- package/dist/gs/time/time.js.map +1 -0
- package/package.json +7 -6
- package/builtin/builtin.go +0 -11
- package/builtin/builtin.ts +0 -2379
- package/dist/builtin/builtin.d.ts +0 -513
- package/dist/builtin/builtin.js +0 -1686
- package/dist/builtin/builtin.js.map +0 -1
package/compiler/type-assert.go
CHANGED
|
@@ -4,7 +4,6 @@ import (
|
|
|
4
4
|
"fmt"
|
|
5
5
|
"go/ast"
|
|
6
6
|
"go/token"
|
|
7
|
-
"go/types"
|
|
8
7
|
"strings"
|
|
9
8
|
)
|
|
10
9
|
|
|
@@ -46,418 +45,165 @@ func (c *GoToTSCompiler) writeTypeAssert(lhs []ast.Expr, typeAssertExpr *ast.Typ
|
|
|
46
45
|
return fmt.Errorf("type assertion assignment requires exactly 2 variables on LHS, got %d", len(lhs))
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
valueIsBlank := false
|
|
51
|
-
okIsBlank := false
|
|
52
|
-
var valueName string
|
|
48
|
+
var okIsBlank bool
|
|
53
49
|
var okName string
|
|
54
|
-
var valueIdent *ast.Ident
|
|
55
|
-
var okIdent *ast.Ident
|
|
56
50
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
} else {
|
|
62
|
-
valueName = valId.Name
|
|
63
|
-
}
|
|
64
|
-
} else {
|
|
65
|
-
return fmt.Errorf("unhandled LHS expression type for value in type assertion: %T", lhs[0])
|
|
51
|
+
okExpr := lhs[1]
|
|
52
|
+
okIdent, ok := okExpr.(*ast.Ident)
|
|
53
|
+
if !ok {
|
|
54
|
+
return fmt.Errorf("ok expression is not an identifier: %T", okExpr)
|
|
66
55
|
}
|
|
56
|
+
okIsBlank = okIdent.Name == "_"
|
|
57
|
+
okName = okIdent.Name
|
|
67
58
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
59
|
+
valueExpr := lhs[0]
|
|
60
|
+
|
|
61
|
+
// Determine if 'ok' variable is new in 'tok == token.DEFINE' context.
|
|
62
|
+
// This uses types.Info.Defs to see if the identifier is defined by this statement.
|
|
63
|
+
var okIsNewInDefine bool
|
|
64
|
+
if tok == token.DEFINE && !okIsBlank {
|
|
65
|
+
if c.pkg.TypesInfo.Defs[okIdent] != nil {
|
|
66
|
+
okIsNewInDefine = true
|
|
74
67
|
}
|
|
75
|
-
} else {
|
|
76
|
-
return fmt.Errorf("unhandled LHS expression type for ok in type assertion: %T", lhs[1])
|
|
77
68
|
}
|
|
78
69
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
anyNewVars := false
|
|
87
|
-
allNewVars := true
|
|
70
|
+
switch vLHS := valueExpr.(type) {
|
|
71
|
+
case *ast.Ident:
|
|
72
|
+
var valueIsBlank bool
|
|
73
|
+
var valueName string
|
|
74
|
+
valueIdent := vLHS
|
|
75
|
+
valueIsBlank = (valueIdent.Name == "_")
|
|
76
|
+
valueName = valueIdent.Name
|
|
88
77
|
|
|
89
|
-
|
|
90
|
-
if !valueIsBlank {
|
|
91
|
-
if
|
|
92
|
-
|
|
93
|
-
valueIsNew = false
|
|
94
|
-
allNewVars = false
|
|
95
|
-
}
|
|
96
|
-
if valueIsNew {
|
|
97
|
-
anyNewVars = true
|
|
78
|
+
var valueIsNewInDefine bool
|
|
79
|
+
if tok == token.DEFINE && !valueIsBlank {
|
|
80
|
+
if c.pkg.TypesInfo.Defs[valueIdent] != nil { // valueIdent is defined by this statement
|
|
81
|
+
valueIsNewInDefine = true
|
|
98
82
|
}
|
|
99
83
|
}
|
|
100
84
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// If it's in Uses, it's referenced elsewhere, so it exists
|
|
104
|
-
okIsNew = false
|
|
105
|
-
allNewVars = false
|
|
106
|
-
}
|
|
107
|
-
if okIsNew {
|
|
108
|
-
anyNewVars = true
|
|
109
|
-
}
|
|
110
|
-
}
|
|
85
|
+
writeEndParen := false // For wrapping assignment in parens to make it an expression
|
|
86
|
+
letDestructure := false // True if 'let { value: v, ok: o } = ...' is appropriate
|
|
111
87
|
|
|
112
|
-
if
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if
|
|
88
|
+
if tok == token.DEFINE {
|
|
89
|
+
anyNewVars := (valueIsNewInDefine && !valueIsBlank) || (okIsNewInDefine && !okIsBlank)
|
|
90
|
+
// allVarsNewOrBlank means suitable for a single `let {v,o} = ...` destructuring
|
|
91
|
+
allVarsNewOrBlank := (valueIsBlank || valueIsNewInDefine) && (okIsBlank || okIsNewInDefine)
|
|
92
|
+
|
|
93
|
+
if allVarsNewOrBlank && anyNewVars {
|
|
94
|
+
letDestructure = true
|
|
95
|
+
} else if anyNewVars { // Mixed: some new, some existing. Declare new ones separately.
|
|
96
|
+
if !valueIsBlank && valueIsNewInDefine {
|
|
97
|
+
c.tsw.WriteLiterally("let ")
|
|
98
|
+
c.tsw.WriteLiterally(valueName)
|
|
121
99
|
c.tsw.WriteLiterally(": ")
|
|
122
|
-
c.
|
|
100
|
+
c.WriteTypeExpr(assertedType) // Use WriteTypeExpr for TS type annotation
|
|
101
|
+
c.tsw.WriteLine("")
|
|
123
102
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
c.tsw.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
c.tsw.WriteLiterally("
|
|
103
|
+
if !okIsBlank && okIsNewInDefine {
|
|
104
|
+
c.tsw.WriteLiterally("let ")
|
|
105
|
+
c.tsw.WriteLiterally(okName)
|
|
106
|
+
c.tsw.WriteLiterally(": boolean")
|
|
107
|
+
c.tsw.WriteLine("")
|
|
108
|
+
}
|
|
109
|
+
c.tsw.WriteLiterally("(") // Parenthesize the assignment part
|
|
110
|
+
writeEndParen = true
|
|
111
|
+
} else { // All variables exist
|
|
112
|
+
c.tsw.WriteLiterally("(")
|
|
113
|
+
writeEndParen = true
|
|
114
|
+
}
|
|
115
|
+
} else { // tok == token.ASSIGN
|
|
116
|
+
c.tsw.WriteLiterally("(")
|
|
138
117
|
writeEndParen = true
|
|
139
118
|
}
|
|
140
|
-
} else {
|
|
141
|
-
c.tsw.WriteLiterally("(")
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
c.tsw.WriteLiterally("{ ")
|
|
145
|
-
// Dynamically build the destructuring pattern
|
|
146
|
-
parts := []string{}
|
|
147
|
-
if !valueIsBlank {
|
|
148
|
-
parts = append(parts, fmt.Sprintf("value: %s", valueName))
|
|
149
|
-
}
|
|
150
|
-
if !okIsBlank {
|
|
151
|
-
parts = append(parts, fmt.Sprintf("ok: %s", okName))
|
|
152
|
-
}
|
|
153
|
-
c.tsw.WriteLiterally(strings.Join(parts, ", "))
|
|
154
|
-
c.tsw.WriteLiterally(" } = $.typeAssert<")
|
|
155
|
-
|
|
156
|
-
// Write the asserted type for the generic
|
|
157
|
-
c.WriteTypeExpr(assertedType)
|
|
158
|
-
c.tsw.WriteLiterally(">(")
|
|
159
|
-
|
|
160
|
-
// Write the interface expression
|
|
161
|
-
if err := c.WriteValueExpr(interfaceExpr); err != nil {
|
|
162
|
-
return fmt.Errorf("failed to write interface expression in type assertion call: %w", err)
|
|
163
|
-
}
|
|
164
|
-
c.tsw.WriteLiterally(", ")
|
|
165
|
-
|
|
166
|
-
// Use structured type information for all types
|
|
167
|
-
switch typeExpr := assertedType.(type) {
|
|
168
|
-
case *ast.MapType:
|
|
169
|
-
c.tsw.WriteLiterally("{")
|
|
170
|
-
c.tsw.WriteLiterally("kind: $.TypeKind.Map, ")
|
|
171
|
-
|
|
172
|
-
c.tsw.WriteLiterally("keyType: ")
|
|
173
|
-
if ident, ok := typeExpr.Key.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
174
|
-
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
175
|
-
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
176
|
-
} else {
|
|
177
|
-
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
178
|
-
}
|
|
179
|
-
} else {
|
|
180
|
-
c.writeTypeDescription(typeExpr.Key)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
c.tsw.WriteLiterally(", ")
|
|
184
|
-
|
|
185
|
-
// Add element type
|
|
186
|
-
c.tsw.WriteLiterally("elemType: ")
|
|
187
|
-
if ident, ok := typeExpr.Value.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
188
|
-
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
189
|
-
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
190
|
-
} else {
|
|
191
|
-
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
c.writeTypeDescription(typeExpr.Value)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
c.tsw.WriteLiterally("}")
|
|
198
|
-
case *ast.ArrayType:
|
|
199
|
-
// Determine if it's a slice or array
|
|
200
|
-
typeKind := "$.TypeKind.Slice"
|
|
201
|
-
if typeExpr.Len != nil {
|
|
202
|
-
typeKind = "$.TypeKind.Array"
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Create a type descriptor object
|
|
206
|
-
c.tsw.WriteLiterally("{")
|
|
207
|
-
c.tsw.WriteLiterallyf("kind: %s, ", typeKind)
|
|
208
|
-
|
|
209
|
-
// Add element type
|
|
210
|
-
c.tsw.WriteLiterally("elemType: ")
|
|
211
|
-
if ident, ok := typeExpr.Elt.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
212
|
-
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
213
|
-
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
214
|
-
} else {
|
|
215
|
-
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
216
|
-
}
|
|
217
|
-
} else {
|
|
218
|
-
c.writeTypeDescription(typeExpr.Elt)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
c.tsw.WriteLiterally("}")
|
|
222
|
-
case *ast.StructType:
|
|
223
|
-
// For struct types, create a type descriptor object
|
|
224
|
-
c.tsw.WriteLiterally("{")
|
|
225
|
-
c.tsw.WriteLiterally("kind: $.TypeKind.Struct")
|
|
226
|
-
|
|
227
|
-
// Get the type name if available
|
|
228
|
-
typeName := c.getTypeNameString(assertedType)
|
|
229
|
-
if typeName != "unknown" {
|
|
230
|
-
c.tsw.WriteLiterallyf(", name: '%s'", typeName)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if typeExpr.Fields != nil && typeExpr.Fields.List != nil {
|
|
234
|
-
// Add fields property to provide type information
|
|
235
|
-
c.tsw.WriteLiterally(", fields: {")
|
|
236
|
-
|
|
237
|
-
hasFields := false
|
|
238
|
-
for _, field := range typeExpr.Fields.List {
|
|
239
|
-
if len(field.Names) > 0 {
|
|
240
|
-
for _, name := range field.Names {
|
|
241
|
-
if hasFields {
|
|
242
|
-
c.tsw.WriteLiterally(", ")
|
|
243
|
-
}
|
|
244
|
-
c.tsw.WriteLiterally(fmt.Sprintf("'%s': ", name.Name))
|
|
245
|
-
c.writeTypeDescription(field.Type)
|
|
246
|
-
hasFields = true
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
119
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
c.tsw.WriteLiterally(", fields: {}")
|
|
120
|
+
if letDestructure {
|
|
121
|
+
c.tsw.WriteLiterally("let ")
|
|
254
122
|
}
|
|
255
123
|
|
|
256
|
-
//
|
|
257
|
-
c.tsw.WriteLiterally("
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
c.tsw.WriteLiterally("{")
|
|
262
|
-
c.tsw.WriteLiterally("kind: $.TypeKind.Interface")
|
|
263
|
-
|
|
264
|
-
// Get the type name if available
|
|
265
|
-
typeName := c.getTypeNameString(assertedType)
|
|
266
|
-
if typeName != "unknown" {
|
|
267
|
-
c.tsw.WriteLiterallyf(", name: '%s'", typeName)
|
|
124
|
+
// Write the destructuring part: { value: v, ok: o }
|
|
125
|
+
c.tsw.WriteLiterally("{ ")
|
|
126
|
+
parts := []string{}
|
|
127
|
+
if !valueIsBlank {
|
|
128
|
+
parts = append(parts, fmt.Sprintf("value: %s", valueName))
|
|
268
129
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
c.tsw.WriteLiterally(", methods: []")
|
|
272
|
-
|
|
273
|
-
c.tsw.WriteLiterally("}")
|
|
274
|
-
case *ast.StarExpr:
|
|
275
|
-
c.tsw.WriteLiterally("{")
|
|
276
|
-
c.tsw.WriteLiterally("kind: $.TypeKind.Pointer")
|
|
277
|
-
|
|
278
|
-
// Add element type if it's a struct type or named type
|
|
279
|
-
if structType, ok := typeExpr.X.(*ast.StructType); ok {
|
|
280
|
-
c.tsw.WriteLiterally(", elemType: ")
|
|
281
|
-
c.writeTypeDescription(structType)
|
|
282
|
-
} else if ident, ok := typeExpr.X.(*ast.Ident); ok {
|
|
283
|
-
c.tsw.WriteLiterallyf(", elemType: '%s'", ident.Name)
|
|
130
|
+
if !okIsBlank {
|
|
131
|
+
parts = append(parts, fmt.Sprintf("ok: %s", okName))
|
|
284
132
|
}
|
|
285
|
-
|
|
286
|
-
c.tsw.WriteLiterally("}")
|
|
287
|
-
|
|
288
|
-
c.tsw.WriteLiterally("
|
|
289
|
-
c.
|
|
290
|
-
|
|
291
|
-
// Add element type
|
|
292
|
-
c.tsw.WriteLiterally(", elemType: ")
|
|
293
|
-
if ident, ok := typeExpr.Value.(*ast.Ident); ok && isPrimitiveType(ident.Name) {
|
|
294
|
-
if tsType, ok := GoBuiltinToTypescript(ident.Name); ok {
|
|
295
|
-
c.tsw.WriteLiterallyf("'%s'", tsType)
|
|
296
|
-
} else {
|
|
297
|
-
c.tsw.WriteLiterallyf("'%s'", ident.Name) // Fallback
|
|
298
|
-
}
|
|
299
|
-
} else {
|
|
300
|
-
c.writeTypeDescription(typeExpr.Value)
|
|
133
|
+
c.tsw.WriteLiterally(strings.Join(parts, ", "))
|
|
134
|
+
c.tsw.WriteLiterally(" } = $.typeAssert<")
|
|
135
|
+
c.WriteTypeExpr(assertedType) // Generic: <AssertedTypeTS>
|
|
136
|
+
c.tsw.WriteLiterally(">(")
|
|
137
|
+
if err := c.WriteValueExpr(interfaceExpr); err != nil { // Arg1: interfaceExpr
|
|
138
|
+
return fmt.Errorf("failed to write interface expression in type assertion call: %w", err)
|
|
301
139
|
}
|
|
140
|
+
c.tsw.WriteLiterally(", ")
|
|
141
|
+
c.writeTypeDescription(assertedType) // Arg2: type info for runtime
|
|
142
|
+
c.tsw.WriteLiterally(")")
|
|
302
143
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
case ast.SEND:
|
|
306
|
-
c.tsw.WriteLiterally("'send'")
|
|
307
|
-
case ast.RECV:
|
|
308
|
-
c.tsw.WriteLiterally("'receive'")
|
|
309
|
-
case ast.SEND | ast.RECV: // bidirectional
|
|
310
|
-
c.tsw.WriteLiterally("'both'")
|
|
311
|
-
default:
|
|
312
|
-
// This should not happen, but just in case
|
|
313
|
-
c.tsw.WriteLiterally("'both'")
|
|
144
|
+
if writeEndParen {
|
|
145
|
+
c.tsw.WriteLiterally(")")
|
|
314
146
|
}
|
|
147
|
+
c.tsw.WriteLine("")
|
|
315
148
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
//
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
149
|
+
case *ast.SelectorExpr:
|
|
150
|
+
// Handle s.field, ok := expr.(Type)
|
|
151
|
+
tempValName := "_gs_ta_val_" // Fixed name for temporary value
|
|
152
|
+
tempOkName := "_gs_ta_ok_" // Fixed name for temporary ok status
|
|
153
|
+
|
|
154
|
+
// Declare temporary variables:
|
|
155
|
+
// let _gs_ta_val_: AssertedTypeTS;
|
|
156
|
+
c.tsw.WriteLiterally("let ")
|
|
157
|
+
c.tsw.WriteLiterally(tempValName)
|
|
158
|
+
c.tsw.WriteLiterally(": ")
|
|
159
|
+
c.WriteTypeExpr(assertedType) // TypeScript type for assertedType
|
|
160
|
+
c.tsw.WriteLine("")
|
|
161
|
+
|
|
162
|
+
// let _gs_ta_ok_: boolean;
|
|
163
|
+
c.tsw.WriteLiterally("let ")
|
|
164
|
+
c.tsw.WriteLiterally(tempOkName)
|
|
165
|
+
c.tsw.WriteLiterally(": boolean")
|
|
166
|
+
c.tsw.WriteLine("")
|
|
167
|
+
|
|
168
|
+
// Perform type assertion into temporary variables:
|
|
169
|
+
// ({ value: _gs_ta_val_, ok: _gs_ta_ok_ } = $.typeAssert<AssertedTypeTS>(expr, "GoTypeStr"));
|
|
170
|
+
c.tsw.WriteLiterally("({ value: ")
|
|
171
|
+
c.tsw.WriteLiterally(tempValName)
|
|
172
|
+
c.tsw.WriteLiterally(", ok: ")
|
|
173
|
+
c.tsw.WriteLiterally(tempOkName)
|
|
174
|
+
c.tsw.WriteLiterally(" } = $.typeAssert<")
|
|
175
|
+
c.WriteTypeExpr(assertedType) // Generic: <AssertedTypeTS>
|
|
176
|
+
c.tsw.WriteLiterally(">(")
|
|
177
|
+
if err := c.WriteValueExpr(interfaceExpr); err != nil { // Arg1: interfaceExpr
|
|
178
|
+
return fmt.Errorf("failed to write interface expression in type assertion call: %w", err)
|
|
327
179
|
}
|
|
180
|
+
c.tsw.WriteLiterally(", ")
|
|
181
|
+
c.writeTypeDescription(assertedType) // Arg2: type info for runtime
|
|
182
|
+
c.tsw.WriteLine("))")
|
|
328
183
|
|
|
329
|
-
//
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if i > 0 {
|
|
334
|
-
c.tsw.WriteLiterally(", ")
|
|
335
|
-
}
|
|
336
|
-
c.writeTypeDescription(param.Type)
|
|
337
|
-
}
|
|
338
|
-
c.tsw.WriteLiterally("]")
|
|
184
|
+
// Assign temporary value to the selector expression:
|
|
185
|
+
// s.f = _gs_ta_val_;
|
|
186
|
+
if err := c.WriteValueExpr(vLHS); err != nil { // Writes selector expression (e.g., "s.f")
|
|
187
|
+
return fmt.Errorf("failed to write LHS selector expression in type assertion: %w", err)
|
|
339
188
|
}
|
|
189
|
+
c.tsw.WriteLiterally(" = ")
|
|
190
|
+
c.tsw.WriteLiterally(tempValName)
|
|
191
|
+
c.tsw.WriteLine("")
|
|
340
192
|
|
|
341
|
-
//
|
|
342
|
-
if
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
if i > 0 {
|
|
346
|
-
c.tsw.WriteLiterally(", ")
|
|
347
|
-
}
|
|
348
|
-
c.writeTypeDescription(result.Type)
|
|
193
|
+
// Assign temporary ok to the ok variable (e.g., okName = _gs_ta_ok_; or let okName = ...)
|
|
194
|
+
if !okIsBlank {
|
|
195
|
+
if okIsNewInDefine { // okIsNewInDefine was determined earlier based on tok == token.DEFINE and Defs check
|
|
196
|
+
c.tsw.WriteLiterally("let ")
|
|
349
197
|
}
|
|
350
|
-
c.tsw.WriteLiterally(
|
|
198
|
+
c.tsw.WriteLiterally(okName)
|
|
199
|
+
c.tsw.WriteLiterally(" = ")
|
|
200
|
+
c.tsw.WriteLiterally(tempOkName)
|
|
201
|
+
c.tsw.WriteLine("")
|
|
351
202
|
}
|
|
352
203
|
|
|
353
|
-
c.tsw.WriteLiterally("}")
|
|
354
|
-
case *ast.Ident:
|
|
355
|
-
if isPrimitiveType(typeExpr.Name) {
|
|
356
|
-
c.tsw.WriteLiterally("{")
|
|
357
|
-
c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
|
|
358
|
-
|
|
359
|
-
// Use TypeScript equivalent if available
|
|
360
|
-
if tsType, ok := GoBuiltinToTypescript(typeExpr.Name); ok {
|
|
361
|
-
c.tsw.WriteLiterallyf("name: '%s'", tsType) // TODO: use %q?
|
|
362
|
-
} else {
|
|
363
|
-
c.tsw.WriteLiterallyf("name: '%s'", typeExpr.Name)
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
c.tsw.WriteLiterally("}")
|
|
367
|
-
} else {
|
|
368
|
-
// Check if this is a named function type
|
|
369
|
-
isFunctionType := false
|
|
370
|
-
if namedType := c.pkg.TypesInfo.TypeOf(typeExpr); namedType != nil {
|
|
371
|
-
if named, ok := namedType.(*types.Named); ok {
|
|
372
|
-
if _, ok := named.Underlying().(*types.Signature); ok {
|
|
373
|
-
// This is a named function type, generate a FunctionTypeInfo
|
|
374
|
-
isFunctionType = true
|
|
375
|
-
c.tsw.WriteLiterally("{")
|
|
376
|
-
c.tsw.WriteLiterally("kind: $.TypeKind.Function")
|
|
377
|
-
c.tsw.WriteLiterallyf(", name: '%s'", typeExpr.Name)
|
|
378
|
-
|
|
379
|
-
// Get the underlying signature
|
|
380
|
-
signature := named.Underlying().(*types.Signature)
|
|
381
|
-
|
|
382
|
-
// Add params if present
|
|
383
|
-
params := signature.Params()
|
|
384
|
-
if params != nil && params.Len() > 0 {
|
|
385
|
-
c.tsw.WriteLiterally(", params: [")
|
|
386
|
-
for i := 0; i < params.Len(); i++ {
|
|
387
|
-
if i > 0 {
|
|
388
|
-
c.tsw.WriteLiterally(", ")
|
|
389
|
-
}
|
|
390
|
-
// Use basic type info for parameters
|
|
391
|
-
param := params.At(i)
|
|
392
|
-
c.tsw.WriteLiterally("{")
|
|
393
|
-
c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
|
|
394
|
-
|
|
395
|
-
typeName := param.Type().String()
|
|
396
|
-
if tsType, ok := GoBuiltinToTypescript(typeName); ok {
|
|
397
|
-
c.tsw.WriteLiterallyf("name: '%s'", tsType)
|
|
398
|
-
} else {
|
|
399
|
-
c.tsw.WriteLiterallyf("name: '%s'", typeName)
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
c.tsw.WriteLiterally("}")
|
|
403
|
-
}
|
|
404
|
-
c.tsw.WriteLiterally("]")
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// Add results if present
|
|
408
|
-
results := signature.Results()
|
|
409
|
-
if results != nil && results.Len() > 0 {
|
|
410
|
-
c.tsw.WriteLiterally(", results: [")
|
|
411
|
-
for i := 0; i < results.Len(); i++ {
|
|
412
|
-
if i > 0 {
|
|
413
|
-
c.tsw.WriteLiterally(", ")
|
|
414
|
-
}
|
|
415
|
-
result := results.At(i)
|
|
416
|
-
c.tsw.WriteLiterally("{")
|
|
417
|
-
c.tsw.WriteLiterally("kind: $.TypeKind.Basic, ")
|
|
418
|
-
|
|
419
|
-
typeName := result.Type().String()
|
|
420
|
-
if tsType, ok := GoBuiltinToTypescript(typeName); ok {
|
|
421
|
-
c.tsw.WriteLiterallyf("name: '%s'", tsType)
|
|
422
|
-
} else {
|
|
423
|
-
c.tsw.WriteLiterallyf("name: '%s'", typeName)
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
c.tsw.WriteLiterally("}")
|
|
427
|
-
}
|
|
428
|
-
c.tsw.WriteLiterally("]")
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
c.tsw.WriteLiterally("}")
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// Default case for non-function named types
|
|
437
|
-
if !isFunctionType {
|
|
438
|
-
c.tsw.WriteLiterallyf("'%s'", typeExpr.Name)
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
case *ast.SelectorExpr:
|
|
442
|
-
// For imported types like pkg.Type
|
|
443
|
-
if ident, ok := typeExpr.X.(*ast.Ident); ok {
|
|
444
|
-
c.tsw.WriteLiterallyf("'%s.%s'", ident.Name, typeExpr.Sel.Name)
|
|
445
|
-
} else {
|
|
446
|
-
c.tsw.WriteLiterallyf("'%s'", c.getTypeNameString(assertedType))
|
|
447
|
-
}
|
|
448
204
|
default:
|
|
449
|
-
|
|
450
|
-
typeName := c.getTypeNameString(assertedType)
|
|
451
|
-
c.tsw.WriteLiterallyf("'%s'", typeName)
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
c.tsw.WriteLiterally(")")
|
|
455
|
-
|
|
456
|
-
if tok != token.DEFINE || writeEndParen {
|
|
457
|
-
c.tsw.WriteLiterally(")")
|
|
205
|
+
return fmt.Errorf("unhandled LHS expression type for value in type assertion: %T", valueExpr)
|
|
458
206
|
}
|
|
459
207
|
|
|
460
|
-
c.tsw.WriteLine("") // Add newline after the statement
|
|
461
|
-
|
|
462
208
|
return nil
|
|
463
209
|
}
|