goscript 0.0.23 → 0.0.25
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 +2 -2
- package/cmd/goscript/cmd_compile.go +18 -2
- package/compiler/analysis.go +74 -132
- package/compiler/analysis_test.go +220 -0
- package/compiler/assignment.go +37 -43
- package/compiler/builtin_test.go +90 -0
- package/compiler/compiler.go +307 -22
- package/compiler/composite-lit.go +108 -43
- package/compiler/config.go +7 -3
- package/compiler/config_test.go +6 -33
- package/compiler/decl.go +7 -1
- package/compiler/expr-call.go +212 -2
- package/compiler/expr-selector.go +66 -41
- package/compiler/expr-star.go +57 -65
- package/compiler/expr-type.go +1 -1
- package/compiler/expr-value.go +1 -1
- package/compiler/expr.go +125 -20
- package/compiler/field.go +4 -4
- package/compiler/primitive.go +11 -10
- package/compiler/spec-struct.go +3 -3
- package/compiler/spec-value.go +75 -29
- package/compiler/spec.go +9 -3
- package/compiler/stmt-assign.go +36 -2
- package/compiler/stmt-for.go +11 -0
- package/compiler/stmt-range.go +314 -1
- package/compiler/stmt.go +52 -0
- package/compiler/type.go +83 -15
- package/dist/gs/builtin/builtin.d.ts +9 -0
- package/dist/gs/builtin/builtin.js +46 -0
- package/dist/gs/builtin/builtin.js.map +1 -0
- package/dist/gs/builtin/channel.d.ts +193 -0
- package/dist/gs/builtin/channel.js +471 -0
- package/dist/gs/builtin/channel.js.map +1 -0
- package/dist/gs/builtin/defer.d.ts +38 -0
- package/dist/gs/builtin/defer.js +54 -0
- package/dist/gs/builtin/defer.js.map +1 -0
- package/dist/gs/builtin/index.d.ts +1 -0
- package/dist/gs/builtin/index.js +2 -0
- package/dist/gs/builtin/index.js.map +1 -0
- package/dist/gs/builtin/io.d.ts +16 -0
- package/dist/gs/builtin/io.js +15 -0
- package/dist/gs/builtin/io.js.map +1 -0
- package/dist/gs/builtin/map.d.ts +33 -0
- package/dist/gs/builtin/map.js +44 -0
- package/dist/gs/builtin/map.js.map +1 -0
- package/dist/gs/builtin/slice.d.ts +173 -0
- package/dist/gs/builtin/slice.js +799 -0
- package/dist/gs/builtin/slice.js.map +1 -0
- package/dist/gs/builtin/type.d.ts +203 -0
- package/dist/gs/builtin/type.js +744 -0
- package/dist/gs/builtin/type.js.map +1 -0
- package/dist/gs/builtin/varRef.d.ts +14 -0
- package/dist/gs/builtin/varRef.js +14 -0
- package/dist/gs/builtin/varRef.js.map +1 -0
- package/dist/gs/cmp/index.d.ts +4 -0
- package/dist/gs/cmp/index.js +27 -0
- package/dist/gs/cmp/index.js.map +1 -0
- package/dist/gs/context/context.d.ts +26 -0
- package/dist/gs/context/context.js +305 -0
- package/dist/gs/context/context.js.map +1 -0
- package/dist/gs/context/index.d.ts +1 -0
- package/dist/gs/context/index.js +2 -0
- package/dist/gs/context/index.js.map +1 -0
- package/dist/gs/internal/goarch/index.d.ts +6 -0
- package/dist/gs/internal/goarch/index.js +14 -0
- package/dist/gs/internal/goarch/index.js.map +1 -0
- package/dist/gs/iter/index.d.ts +1 -0
- package/dist/gs/iter/index.js +2 -0
- package/dist/gs/iter/index.js.map +1 -0
- package/dist/gs/iter/iter.d.ts +4 -0
- package/dist/gs/iter/iter.js +91 -0
- package/dist/gs/iter/iter.js.map +1 -0
- package/dist/gs/math/bits/index.d.ts +47 -0
- package/dist/gs/math/bits/index.js +298 -0
- package/dist/gs/math/bits/index.js.map +1 -0
- package/dist/gs/runtime/index.d.ts +1 -0
- package/dist/gs/runtime/index.js +2 -0
- package/dist/gs/runtime/index.js.map +1 -0
- package/dist/gs/runtime/runtime.d.ts +41 -0
- package/dist/gs/runtime/runtime.js +158 -0
- package/dist/gs/runtime/runtime.js.map +1 -0
- package/dist/gs/slices/index.d.ts +1 -0
- package/dist/gs/slices/index.js +2 -0
- package/dist/gs/slices/index.js.map +1 -0
- package/dist/gs/slices/slices.d.ts +8 -0
- package/dist/gs/slices/slices.js +20 -0
- package/dist/gs/slices/slices.js.map +1 -0
- package/dist/gs/time/index.d.ts +1 -0
- package/dist/gs/time/index.js +2 -0
- package/dist/gs/time/index.js.map +1 -0
- package/dist/gs/time/time.d.ts +57 -0
- package/dist/gs/time/time.js +208 -0
- package/dist/gs/time/time.js.map +1 -0
- package/package.json +3 -2
package/compiler/stmt.go
CHANGED
|
@@ -28,6 +28,8 @@ import (
|
|
|
28
28
|
// - Go statements (`ast.GoStmt`): `WriteStmtGo`.
|
|
29
29
|
// - Select statements (`ast.SelectStmt`): `WriteStmtSelect`.
|
|
30
30
|
// - Branch statements (`ast.BranchStmt`): `WriteStmtBranch`.
|
|
31
|
+
// - Type switch statements (`ast.TypeSwitchStmt`): `WriteStmtTypeSwitch`.
|
|
32
|
+
// - Labeled statements (`ast.LabeledStmt`): `WriteStmtLabeled`.
|
|
31
33
|
//
|
|
32
34
|
// If an unknown statement type is encountered, it returns an error.
|
|
33
35
|
func (c *GoToTSCompiler) WriteStmt(a ast.Stmt) error {
|
|
@@ -109,6 +111,10 @@ func (c *GoToTSCompiler) WriteStmt(a ast.Stmt) error {
|
|
|
109
111
|
if err := c.WriteStmtTypeSwitch(exp); err != nil {
|
|
110
112
|
return fmt.Errorf("failed to write type switch statement: %w", err)
|
|
111
113
|
}
|
|
114
|
+
case *ast.LabeledStmt:
|
|
115
|
+
if err := c.WriteStmtLabeled(exp); err != nil {
|
|
116
|
+
return fmt.Errorf("failed to write labeled statement: %w", err)
|
|
117
|
+
}
|
|
112
118
|
default:
|
|
113
119
|
return errors.Errorf("unknown statement: %#v\n", a)
|
|
114
120
|
}
|
|
@@ -292,6 +298,37 @@ func (c *GoToTSCompiler) WriteStmtGo(exp *ast.GoStmt) error {
|
|
|
292
298
|
c.tsw.WriteLiterally(")")
|
|
293
299
|
c.tsw.WriteLine("")
|
|
294
300
|
|
|
301
|
+
c.tsw.Indent(-1)
|
|
302
|
+
c.tsw.WriteLine("})") // Close the queueMicrotask callback and the statement
|
|
303
|
+
case *ast.TypeAssertExpr:
|
|
304
|
+
// Handle type assertion expressions: go x.(func())()
|
|
305
|
+
// We assume this is always synchronous (no async function returned by type assertion)
|
|
306
|
+
c.tsw.WriteLiterally("queueMicrotask(() => {")
|
|
307
|
+
|
|
308
|
+
c.tsw.Indent(1)
|
|
309
|
+
c.tsw.WriteLine("")
|
|
310
|
+
|
|
311
|
+
// Write the type assertion call
|
|
312
|
+
if err := c.WriteTypeAssertExpr(fun); err != nil {
|
|
313
|
+
return fmt.Errorf("failed to write type assertion expression in goroutine: %w", err)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Add non-null assertion since mustTypeAssert throws on failure rather than returning null
|
|
317
|
+
c.tsw.WriteLiterally("!")
|
|
318
|
+
|
|
319
|
+
// Write the function arguments
|
|
320
|
+
c.tsw.WriteLiterally("(")
|
|
321
|
+
for i, arg := range callExpr.Args {
|
|
322
|
+
if i != 0 {
|
|
323
|
+
c.tsw.WriteLiterally(", ")
|
|
324
|
+
}
|
|
325
|
+
if err := c.WriteValueExpr(arg); err != nil {
|
|
326
|
+
return fmt.Errorf("failed to write argument %d in goroutine type assertion function call: %w", i, err)
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
c.tsw.WriteLiterally(")")
|
|
330
|
+
c.tsw.WriteLine("")
|
|
331
|
+
|
|
295
332
|
c.tsw.Indent(-1)
|
|
296
333
|
c.tsw.WriteLine("})") // Close the queueMicrotask callback and the statement
|
|
297
334
|
default:
|
|
@@ -790,3 +827,18 @@ func (c *GoToTSCompiler) WriteStmtDefer(exp *ast.DeferStmt) error {
|
|
|
790
827
|
|
|
791
828
|
return nil
|
|
792
829
|
}
|
|
830
|
+
|
|
831
|
+
// WriteStmtLabeled handles labeled statements (ast.LabeledStmt), such as "label: statement".
|
|
832
|
+
// In TypeScript, this translates to "label: statement" directly.
|
|
833
|
+
func (c *GoToTSCompiler) WriteStmtLabeled(stmt *ast.LabeledStmt) error {
|
|
834
|
+
// Write the label name followed by a colon
|
|
835
|
+
c.tsw.WriteLiterally(stmt.Label.Name)
|
|
836
|
+
c.tsw.WriteLiterally(": ")
|
|
837
|
+
|
|
838
|
+
// Write the labeled statement
|
|
839
|
+
if err := c.WriteStmt(stmt.Stmt); err != nil {
|
|
840
|
+
return fmt.Errorf("failed to write labeled statement: %w", err)
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
return nil
|
|
844
|
+
}
|
package/compiler/type.go
CHANGED
|
@@ -16,7 +16,7 @@ const (
|
|
|
16
16
|
GoTypeContextGeneral GoTypeContext = iota
|
|
17
17
|
// GoTypeContextFunctionReturn is used when translating types for function return values.
|
|
18
18
|
// In this context, pointer-to-struct types become `ClassName | null` instead of
|
|
19
|
-
// `$.
|
|
19
|
+
// `$.VarRef<ClassName> | null` because function return values cannot be addressed.
|
|
20
20
|
GoTypeContextFunctionReturn
|
|
21
21
|
)
|
|
22
22
|
|
|
@@ -27,7 +27,7 @@ const (
|
|
|
27
27
|
// The context parameter controls how certain types (especially pointers) are handled:
|
|
28
28
|
// - GoTypeContextGeneral: Standard type translation
|
|
29
29
|
// - GoTypeContextFunctionReturn: Special handling for function return types where
|
|
30
|
-
// pointer-to-struct types become `ClassName | null` instead of `$.
|
|
30
|
+
// pointer-to-struct types become `ClassName | null` instead of `$.VarRef<ClassName> | null`
|
|
31
31
|
//
|
|
32
32
|
// It handles nil types as 'any' with a comment, and dispatches to appropriate
|
|
33
33
|
// type-specific writers for all other recognized Go types.
|
|
@@ -47,7 +47,7 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type, context GoTypeContext) {
|
|
|
47
47
|
if context == GoTypeContextFunctionReturn {
|
|
48
48
|
c.writePointerTypeForFunctionReturn(t)
|
|
49
49
|
} else {
|
|
50
|
-
c.WritePointerType(t)
|
|
50
|
+
c.WritePointerType(t, context)
|
|
51
51
|
}
|
|
52
52
|
case *types.Slice:
|
|
53
53
|
c.WriteSliceType(t)
|
|
@@ -68,6 +68,15 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type, context GoTypeContext) {
|
|
|
68
68
|
case *types.TypeParam:
|
|
69
69
|
// For type parameters, write the type parameter name (e.g., "T", "K", etc.)
|
|
70
70
|
c.tsw.WriteLiterally(t.Obj().Name())
|
|
71
|
+
case *types.Union:
|
|
72
|
+
// Handle union types (e.g., string | []byte)
|
|
73
|
+
for i := 0; i < t.Len(); i++ {
|
|
74
|
+
if i > 0 {
|
|
75
|
+
c.tsw.WriteLiterally(" | ")
|
|
76
|
+
}
|
|
77
|
+
term := t.Term(i)
|
|
78
|
+
c.WriteGoType(term.Type(), context)
|
|
79
|
+
}
|
|
71
80
|
default:
|
|
72
81
|
// For other types, just write "any" and add a comment
|
|
73
82
|
c.tsw.WriteLiterally("any")
|
|
@@ -78,7 +87,7 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type, context GoTypeContext) {
|
|
|
78
87
|
// writePointerTypeForFunctionReturn translates a Go pointer type (*T) to its TypeScript
|
|
79
88
|
// equivalent for function return types. Unlike WritePointerType, this function
|
|
80
89
|
// handles pointer-to-struct types specially: they become `ClassName | null` instead
|
|
81
|
-
// of `$.
|
|
90
|
+
// of `$.VarRef<ClassName> | null` because function return values cannot be addressed.
|
|
82
91
|
func (c *GoToTSCompiler) writePointerTypeForFunctionReturn(t *types.Pointer) {
|
|
83
92
|
elemType := t.Elem()
|
|
84
93
|
|
|
@@ -93,8 +102,8 @@ func (c *GoToTSCompiler) writePointerTypeForFunctionReturn(t *types.Pointer) {
|
|
|
93
102
|
c.WriteGoType(elemType, GoTypeContextFunctionReturn)
|
|
94
103
|
c.tsw.WriteLiterally(" | null")
|
|
95
104
|
} else {
|
|
96
|
-
// For pointer-to-primitive in function returns, still use
|
|
97
|
-
c.tsw.WriteLiterally("$.
|
|
105
|
+
// For pointer-to-primitive in function returns, still use varRefing
|
|
106
|
+
c.tsw.WriteLiterally("$.VarRef<")
|
|
98
107
|
c.WriteGoType(elemType, GoTypeContextFunctionReturn)
|
|
99
108
|
c.tsw.WriteLiterally("> | null")
|
|
100
109
|
}
|
|
@@ -202,7 +211,8 @@ func (c *GoToTSCompiler) WriteBasicType(t *types.Basic) {
|
|
|
202
211
|
|
|
203
212
|
// WriteNamedType translates a Go named type to its TypeScript equivalent.
|
|
204
213
|
// It specially handles the error interface as $.GoError, and uses the original
|
|
205
|
-
// type name for other named types. For
|
|
214
|
+
// type name for other named types. For imported types, it writes the qualified
|
|
215
|
+
// name using the import alias found from the analysis imports. For generic types, it includes type arguments.
|
|
206
216
|
func (c *GoToTSCompiler) WriteNamedType(t *types.Named) {
|
|
207
217
|
// Check if the named type is the error interface
|
|
208
218
|
if iface, ok := t.Underlying().(*types.Interface); ok && iface.String() == "interface{Error() string}" {
|
|
@@ -210,7 +220,40 @@ func (c *GoToTSCompiler) WriteNamedType(t *types.Named) {
|
|
|
210
220
|
return
|
|
211
221
|
}
|
|
212
222
|
|
|
213
|
-
//
|
|
223
|
+
// Check if this type is from an imported package
|
|
224
|
+
typePkg := t.Obj().Pkg()
|
|
225
|
+
if typePkg != nil && typePkg != c.pkg.Types {
|
|
226
|
+
// This type is from an imported package, find the import alias
|
|
227
|
+
typePkgPath := typePkg.Path()
|
|
228
|
+
|
|
229
|
+
// Try to find the import alias by matching the package path
|
|
230
|
+
for importAlias, _ := range c.analysis.Imports {
|
|
231
|
+
// The importAlias could be either the explicit alias or the default package name
|
|
232
|
+
// If it's the default package name, it should match the last segment of the path
|
|
233
|
+
defaultPkgName := packageNameFromGoPath(typePkgPath)
|
|
234
|
+
if importAlias == defaultPkgName || importAlias == typePkgPath {
|
|
235
|
+
// Write the qualified name: importAlias.TypeName
|
|
236
|
+
c.tsw.WriteLiterally(importAlias)
|
|
237
|
+
c.tsw.WriteLiterally(".")
|
|
238
|
+
c.tsw.WriteLiterally(t.Obj().Name())
|
|
239
|
+
|
|
240
|
+
// For generic types, include type arguments
|
|
241
|
+
if t.TypeArgs() != nil && t.TypeArgs().Len() > 0 {
|
|
242
|
+
c.tsw.WriteLiterally("<")
|
|
243
|
+
for i := 0; i < t.TypeArgs().Len(); i++ {
|
|
244
|
+
if i > 0 {
|
|
245
|
+
c.tsw.WriteLiterally(", ")
|
|
246
|
+
}
|
|
247
|
+
c.WriteGoType(t.TypeArgs().At(i), GoTypeContextGeneral)
|
|
248
|
+
}
|
|
249
|
+
c.tsw.WriteLiterally(">")
|
|
250
|
+
}
|
|
251
|
+
return
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Use Obj().Name() for the original defined name (local types or unmatched imports)
|
|
214
257
|
c.tsw.WriteLiterally(t.Obj().Name())
|
|
215
258
|
|
|
216
259
|
// For generic types, include type arguments
|
|
@@ -227,11 +270,36 @@ func (c *GoToTSCompiler) WriteNamedType(t *types.Named) {
|
|
|
227
270
|
}
|
|
228
271
|
|
|
229
272
|
// WritePointerType translates a Go pointer type (*T) to its TypeScript equivalent.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
273
|
+
func (c *GoToTSCompiler) WritePointerType(t *types.Pointer, context GoTypeContext) {
|
|
274
|
+
elemGoType := t.Elem()
|
|
275
|
+
underlyingElemGoType := elemGoType.Underlying()
|
|
276
|
+
|
|
277
|
+
// Handle pointers to functions: *func(...) -> func(...) | null
|
|
278
|
+
if _, isSignature := underlyingElemGoType.(*types.Signature); isSignature {
|
|
279
|
+
c.WriteGoType(elemGoType, context) // Write the function signature itself, pass context
|
|
280
|
+
c.tsw.WriteLiterally(" | null") // Function pointers are nullable
|
|
281
|
+
return
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Handle pointers to structs or interfaces: *MyStruct -> MyStruct | null
|
|
285
|
+
_, isStruct := underlyingElemGoType.(*types.Struct)
|
|
286
|
+
_, isInterface := underlyingElemGoType.(*types.Interface)
|
|
287
|
+
|
|
288
|
+
if isStruct || isInterface {
|
|
289
|
+
// For pointers to structs or interfaces, the TS type is StructName | null or InterfaceName | null.
|
|
290
|
+
// This aligns with VAR_REFS.md and JS/TS object reference semantics.
|
|
291
|
+
// TODO If the target variable is boxed, we have to wrap with VarRef as well?
|
|
292
|
+
c.WriteGoType(elemGoType, context) // Write the struct/interface type directly, pass context
|
|
293
|
+
c.tsw.WriteLiterally(" | null")
|
|
294
|
+
} else {
|
|
295
|
+
// For pointers to other types (primitives, slices, maps, other pointers like **MyStruct),
|
|
296
|
+
// they are generally represented as $.VarRef<T_ts> | null.
|
|
297
|
+
// Example: *int -> $.VarRef<number> | null
|
|
298
|
+
// Example: **MyStruct -> $.VarRef<MyStruct | null> | null (recursive call handles inner part)
|
|
299
|
+
c.tsw.WriteLiterally("$.VarRef<")
|
|
300
|
+
c.WriteGoType(elemGoType, context) // Translate element type, pass context
|
|
301
|
+
c.tsw.WriteLiterally("> | null") // Pointers are always nullable
|
|
302
|
+
}
|
|
235
303
|
}
|
|
236
304
|
|
|
237
305
|
// WriteSliceType translates a Go slice type ([]T) to its TypeScript equivalent.
|
|
@@ -363,7 +431,7 @@ func (c *GoToTSCompiler) WriteSignatureType(t *types.Signature) {
|
|
|
363
431
|
|
|
364
432
|
// Use parameter name if available, otherwise use p0, p1, etc.
|
|
365
433
|
if param.Name() != "" {
|
|
366
|
-
c.tsw.WriteLiterally(param.Name())
|
|
434
|
+
c.tsw.WriteLiterally(c.sanitizeIdentifier(param.Name()))
|
|
367
435
|
} else {
|
|
368
436
|
c.tsw.WriteLiterallyf("p%d", i)
|
|
369
437
|
}
|
|
@@ -458,7 +526,7 @@ func (c *GoToTSCompiler) writeInterfaceStructure(iface *types.Interface, astNode
|
|
|
458
526
|
if paramName == "" || paramName == "_" {
|
|
459
527
|
paramName = fmt.Sprintf("_p%d", j)
|
|
460
528
|
}
|
|
461
|
-
c.tsw.WriteLiterally(paramName)
|
|
529
|
+
c.tsw.WriteLiterally(c.sanitizeIdentifier(paramName))
|
|
462
530
|
c.tsw.WriteLiterally(": ")
|
|
463
531
|
c.WriteGoType(paramVar.Type(), GoTypeContextGeneral) // Recursive call for param type
|
|
464
532
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './varRef.js';
|
|
2
|
+
export * from './channel.js';
|
|
3
|
+
export * from './defer.js';
|
|
4
|
+
export * from './io.js';
|
|
5
|
+
export * from './map.js';
|
|
6
|
+
export * from './slice.js';
|
|
7
|
+
export * from './type.js';
|
|
8
|
+
export declare function copy<T>(dst: T[], src: T[]): number;
|
|
9
|
+
export declare function multiplyDuration(duration: any, multiplier: number): any;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export * from './varRef.js';
|
|
2
|
+
export * from './channel.js';
|
|
3
|
+
export * from './defer.js';
|
|
4
|
+
export * from './io.js';
|
|
5
|
+
export * from './map.js';
|
|
6
|
+
export * from './slice.js';
|
|
7
|
+
export * from './type.js';
|
|
8
|
+
// Copy is the Go builtin function that copies the contents of one slice to another.
|
|
9
|
+
// It returns the number of elements copied.
|
|
10
|
+
export function copy(dst, src) {
|
|
11
|
+
const n = Math.min(dst.length, src.length);
|
|
12
|
+
for (let i = 0; i < n; i++) {
|
|
13
|
+
dst[i] = src[i];
|
|
14
|
+
}
|
|
15
|
+
return n;
|
|
16
|
+
}
|
|
17
|
+
// Duration multiplication helper for time package operations
|
|
18
|
+
// Handles expressions like time.Hour * 24
|
|
19
|
+
export function multiplyDuration(duration, multiplier) {
|
|
20
|
+
// Check if duration has a multiply method (like our Duration class)
|
|
21
|
+
if (duration && typeof duration.multiply === 'function') {
|
|
22
|
+
return duration.multiply(multiplier);
|
|
23
|
+
}
|
|
24
|
+
// Check if duration has a valueOf method for numeric operations
|
|
25
|
+
if (duration && typeof duration.valueOf === 'function') {
|
|
26
|
+
const numValue = duration.valueOf();
|
|
27
|
+
// Return an object with the same structure but multiplied value
|
|
28
|
+
if (typeof numValue === 'number') {
|
|
29
|
+
// Try to create a new instance of the same type
|
|
30
|
+
if (duration.constructor) {
|
|
31
|
+
return new duration.constructor(numValue * multiplier);
|
|
32
|
+
}
|
|
33
|
+
// Fallback: return a simple object with valueOf
|
|
34
|
+
return {
|
|
35
|
+
valueOf: () => numValue * multiplier,
|
|
36
|
+
toString: () => (numValue * multiplier).toString() + "ns"
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Fallback for simple numeric values
|
|
41
|
+
if (typeof duration === 'number') {
|
|
42
|
+
return duration * multiplier;
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`Cannot multiply duration of type ${typeof duration}`);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=builtin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../../gs/builtin/builtin.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AAEzB,oFAAoF;AACpF,4CAA4C;AAC5C,MAAM,UAAU,IAAI,CAAI,GAAQ,EAAE,GAAQ;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,6DAA6D;AAC7D,0CAA0C;AAC1C,MAAM,UAAU,gBAAgB,CAAC,QAAa,EAAE,UAAkB;IAChE,oEAAoE;IACpE,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACxD,OAAO,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,gEAAgE;IAChE,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QACpC,gEAAgE;QAChE,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,gDAAgD;YAChD,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACzB,OAAO,IAAI,QAAQ,CAAC,WAAW,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC;YACzD,CAAC;YACD,gDAAgD;YAChD,OAAO;gBACL,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,GAAG,UAAU;gBACpC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,QAAQ,EAAE,GAAG,IAAI;aAC1D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,QAAQ,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oCAAoC,OAAO,QAAQ,EAAE,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the result of a channel receive operation with 'ok' value
|
|
3
|
+
*/
|
|
4
|
+
export interface ChannelReceiveResult<T> {
|
|
5
|
+
value: T;
|
|
6
|
+
ok: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Represents a result from a select operation
|
|
10
|
+
*/
|
|
11
|
+
export interface SelectResult<T> {
|
|
12
|
+
value: T;
|
|
13
|
+
ok: boolean;
|
|
14
|
+
id: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Represents a Go channel in TypeScript.
|
|
18
|
+
* Supports asynchronous sending and receiving of values.
|
|
19
|
+
*/
|
|
20
|
+
export interface Channel<T> {
|
|
21
|
+
/**
|
|
22
|
+
* Sends a value to the channel.
|
|
23
|
+
* Returns a promise that resolves when the value is accepted by the channel.
|
|
24
|
+
* @param value The value to send.
|
|
25
|
+
*/
|
|
26
|
+
send(value: T): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Receives a value from the channel.
|
|
29
|
+
* Returns a promise that resolves with the received value.
|
|
30
|
+
* If the channel is closed, it throws an error.
|
|
31
|
+
*/
|
|
32
|
+
receive(): Promise<T>;
|
|
33
|
+
/**
|
|
34
|
+
* Receives a value from the channel along with a boolean indicating
|
|
35
|
+
* whether the channel is still open.
|
|
36
|
+
* Returns a promise that resolves with {value, ok}.
|
|
37
|
+
* - If channel is open and has data: {value: <data>, ok: true}
|
|
38
|
+
* - If channel is closed and empty: {value: <zero value>, ok: false}
|
|
39
|
+
* - If channel is closed but has remaining buffered data: {value: <data>, ok: true}
|
|
40
|
+
*/
|
|
41
|
+
receiveWithOk(): Promise<ChannelReceiveResult<T>>;
|
|
42
|
+
/**
|
|
43
|
+
* Closes the channel.
|
|
44
|
+
* No more values can be sent to a closed channel.
|
|
45
|
+
* Receive operations on a closed channel return the zero value and ok=false.
|
|
46
|
+
*/
|
|
47
|
+
close(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Used in select statements to create a receive operation promise.
|
|
50
|
+
* @param id An identifier for this case in the select statement
|
|
51
|
+
* @returns Promise that resolves when this case is selected
|
|
52
|
+
*/
|
|
53
|
+
selectReceive(id: number): Promise<SelectResult<T>>;
|
|
54
|
+
/**
|
|
55
|
+
* Used in select statements to create a send operation promise.
|
|
56
|
+
* @param value The value to send
|
|
57
|
+
* @param id An identifier for this case in the select statement
|
|
58
|
+
* @returns Promise that resolves when this case is selected
|
|
59
|
+
*/
|
|
60
|
+
selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
|
|
61
|
+
/**
|
|
62
|
+
* Checks if the channel has data ready to be received without blocking.
|
|
63
|
+
* Used for non-blocking select operations.
|
|
64
|
+
*/
|
|
65
|
+
canReceiveNonBlocking(): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Checks if the channel can accept a send operation without blocking.
|
|
68
|
+
* Used for non-blocking select operations.
|
|
69
|
+
*/
|
|
70
|
+
canSendNonBlocking(): boolean;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Represents a case in a select statement.
|
|
74
|
+
*/
|
|
75
|
+
export interface SelectCase<T> {
|
|
76
|
+
id: number;
|
|
77
|
+
isSend: boolean;
|
|
78
|
+
channel: Channel<any> | ChannelRef<any> | null;
|
|
79
|
+
value?: any;
|
|
80
|
+
onSelected?: (result: SelectResult<T>) => Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Helper for 'select' statements. Takes an array of select cases
|
|
84
|
+
* and resolves when one of them completes, following Go's select rules.
|
|
85
|
+
*
|
|
86
|
+
* @param cases Array of SelectCase objects
|
|
87
|
+
* @param hasDefault Whether there is a default case
|
|
88
|
+
* @returns A promise that resolves with the result of the selected case
|
|
89
|
+
*/
|
|
90
|
+
export declare function selectStatement<T>(cases: SelectCase<T>[], hasDefault?: boolean): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Helper function for channel send operations that handles nil channels correctly.
|
|
93
|
+
* In Go, sending to a nil channel blocks forever.
|
|
94
|
+
* @param channel The channel to send to (can be null)
|
|
95
|
+
* @param value The value to send
|
|
96
|
+
* @returns Promise that never resolves if channel is null, otherwise delegates to channel.send()
|
|
97
|
+
*/
|
|
98
|
+
export declare function chanSend<T>(channel: Channel<T> | ChannelRef<T> | null, value: T): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Helper function for channel receive operations that handles nil channels correctly.
|
|
101
|
+
* In Go, receiving from a nil channel blocks forever.
|
|
102
|
+
* @param channel The channel to receive from (can be null)
|
|
103
|
+
* @returns Promise that never resolves if channel is null, otherwise delegates to channel.receive()
|
|
104
|
+
*/
|
|
105
|
+
export declare function chanRecv<T>(channel: Channel<T> | ChannelRef<T> | null): Promise<T>;
|
|
106
|
+
/**
|
|
107
|
+
* Helper function for channel receive operations with ok value that handles nil channels correctly.
|
|
108
|
+
* In Go, receiving from a nil channel blocks forever.
|
|
109
|
+
* @param channel The channel to receive from (can be null)
|
|
110
|
+
* @returns Promise that never resolves if channel is null, otherwise delegates to channel.receiveWithOk()
|
|
111
|
+
*/
|
|
112
|
+
export declare function chanRecvWithOk<T>(channel: Channel<T> | ChannelRef<T> | null): Promise<ChannelReceiveResult<T>>;
|
|
113
|
+
/**
|
|
114
|
+
* Creates a new channel with the specified buffer size and zero value.
|
|
115
|
+
* @param bufferSize The size of the channel buffer. If 0, creates an unbuffered channel.
|
|
116
|
+
* @param zeroValue The zero value for the channel's element type.
|
|
117
|
+
* @param direction Optional direction for the channel. Default is 'both' (bidirectional).
|
|
118
|
+
* @returns A new channel instance or channel reference.
|
|
119
|
+
*/
|
|
120
|
+
export declare const makeChannel: <T>(bufferSize: number, zeroValue: T, direction?: "send" | "receive" | "both") => Channel<T> | ChannelRef<T>;
|
|
121
|
+
/**
|
|
122
|
+
* Represents a reference to a channel with a specific direction.
|
|
123
|
+
*/
|
|
124
|
+
export interface ChannelRef<T> {
|
|
125
|
+
/**
|
|
126
|
+
* The underlying channel
|
|
127
|
+
*/
|
|
128
|
+
channel: Channel<T>;
|
|
129
|
+
/**
|
|
130
|
+
* The direction of this channel reference
|
|
131
|
+
*/
|
|
132
|
+
direction: 'send' | 'receive' | 'both';
|
|
133
|
+
send(value: T): Promise<void>;
|
|
134
|
+
receive(): Promise<T>;
|
|
135
|
+
receiveWithOk(): Promise<ChannelReceiveResult<T>>;
|
|
136
|
+
close(): void;
|
|
137
|
+
canSendNonBlocking(): boolean;
|
|
138
|
+
canReceiveNonBlocking(): boolean;
|
|
139
|
+
selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
|
|
140
|
+
selectReceive(id: number): Promise<SelectResult<T>>;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* A bidirectional channel reference.
|
|
144
|
+
*/
|
|
145
|
+
export declare class BidirectionalChannelRef<T> implements ChannelRef<T> {
|
|
146
|
+
channel: Channel<T>;
|
|
147
|
+
direction: 'both';
|
|
148
|
+
constructor(channel: Channel<T>);
|
|
149
|
+
send(value: T): Promise<void>;
|
|
150
|
+
receive(): Promise<T>;
|
|
151
|
+
receiveWithOk(): Promise<ChannelReceiveResult<T>>;
|
|
152
|
+
close(): void;
|
|
153
|
+
canSendNonBlocking(): boolean;
|
|
154
|
+
canReceiveNonBlocking(): boolean;
|
|
155
|
+
selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
|
|
156
|
+
selectReceive(id: number): Promise<SelectResult<T>>;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* A send-only channel reference.
|
|
160
|
+
*/
|
|
161
|
+
export declare class SendOnlyChannelRef<T> implements ChannelRef<T> {
|
|
162
|
+
channel: Channel<T>;
|
|
163
|
+
direction: 'send';
|
|
164
|
+
constructor(channel: Channel<T>);
|
|
165
|
+
send(value: T): Promise<void>;
|
|
166
|
+
close(): void;
|
|
167
|
+
canSendNonBlocking(): boolean;
|
|
168
|
+
selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
|
|
169
|
+
receive(): Promise<T>;
|
|
170
|
+
receiveWithOk(): Promise<ChannelReceiveResult<T>>;
|
|
171
|
+
canReceiveNonBlocking(): boolean;
|
|
172
|
+
selectReceive(id: number): Promise<SelectResult<T>>;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* A receive-only channel reference.
|
|
176
|
+
*/
|
|
177
|
+
export declare class ReceiveOnlyChannelRef<T> implements ChannelRef<T> {
|
|
178
|
+
channel: Channel<T>;
|
|
179
|
+
direction: 'receive';
|
|
180
|
+
constructor(channel: Channel<T>);
|
|
181
|
+
receive(): Promise<T>;
|
|
182
|
+
receiveWithOk(): Promise<ChannelReceiveResult<T>>;
|
|
183
|
+
canReceiveNonBlocking(): boolean;
|
|
184
|
+
selectReceive(id: number): Promise<SelectResult<T>>;
|
|
185
|
+
send(value: T): Promise<void>;
|
|
186
|
+
close(): void;
|
|
187
|
+
canSendNonBlocking(): boolean;
|
|
188
|
+
selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Creates a new channel reference with the specified direction.
|
|
192
|
+
*/
|
|
193
|
+
export declare function makeChannelRef<T>(channel: Channel<T>, direction: 'send' | 'receive' | 'both'): ChannelRef<T>;
|