goscript 0.1.0 → 0.1.1
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 +267 -255
- package/cmd/goscript/cmd-test.go +193 -0
- package/cmd/goscript/cmd-test_test.go +76 -0
- package/cmd/goscript/main.go +1 -0
- package/compiler/build-flags.go +38 -0
- package/compiler/compile-request.go +2 -0
- package/compiler/compliance_test.go +0 -8
- package/compiler/gotest/owner.go +24 -0
- package/compiler/gotest/package-result.go +67 -0
- package/compiler/gotest/request.go +145 -0
- package/compiler/gotest/result.go +28 -0
- package/compiler/gotest/runner.go +588 -0
- package/compiler/gotest/runner_test.go +627 -0
- package/compiler/gotest/test.go +9 -0
- package/compiler/index.test.ts +1 -1
- package/compiler/lowered-program.go +71 -19
- package/compiler/lowering.go +5065 -569
- package/compiler/override-facts.go +307 -0
- package/compiler/override-registry.go +50 -189
- package/compiler/override-registry_test.go +47 -0
- package/compiler/package-graph.go +50 -27
- package/compiler/package-graph_test.go +37 -2
- package/compiler/package-test-function.go +9 -0
- package/compiler/package-test-graph-package.go +40 -0
- package/compiler/package-test-graph-variant.go +105 -0
- package/compiler/package-test-graph.go +117 -0
- package/compiler/package-test-graph_test.go +144 -0
- package/compiler/runtime-contract.go +189 -29
- package/compiler/runtime-contract_test.go +44 -30
- package/compiler/semantic-model-types.go +9 -6
- package/compiler/semantic-model.go +538 -38
- package/compiler/semantic-model_test.go +55 -0
- package/compiler/service.go +1 -1
- package/compiler/skeleton_test.go +679 -49
- package/compiler/tsworkspace/owner.go +334 -0
- package/compiler/tsworkspace/owner_test.go +93 -0
- package/compiler/tsworkspace/result.go +17 -0
- package/compiler/typescript-emitter.go +459 -82
- package/compiler/wasm/compile.go +1 -1
- package/compiler/wasm/compile_test.go +61 -11
- package/compiler/wasm_api.go +172 -7
- package/dist/gs/builtin/builtin.d.ts +20 -2
- package/dist/gs/builtin/builtin.js +194 -6
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +8 -0
- package/dist/gs/builtin/channel.js +12 -0
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +22 -2
- package/dist/gs/builtin/slice.js +216 -44
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +5 -2
- package/dist/gs/builtin/type.js +83 -24
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +5 -0
- package/dist/gs/builtin/varRef.js +23 -0
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +48 -44
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +20 -18
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/context/context.d.ts +5 -4
- package/dist/gs/context/context.js +10 -10
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
- package/dist/gs/embed/index.d.ts +7 -0
- package/dist/gs/embed/index.js +16 -0
- package/dist/gs/embed/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +1 -0
- package/dist/gs/encoding/json/index.js +18 -0
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.d.ts +4 -0
- package/dist/gs/errors/errors.js +81 -0
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +4 -4
- package/dist/gs/fmt/fmt.js +42 -11
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +35 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +211 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +825 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +163 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +449 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js +71 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
- package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
- package/dist/gs/go/internal/scannerhooks/index.js +5 -0
- package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
- package/dist/gs/go/scanner/index.d.ts +13 -0
- package/dist/gs/go/scanner/index.js +35 -0
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.d.ts +156 -0
- package/dist/gs/go/token/index.js +500 -4
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/internal/abi/index.d.ts +4 -0
- package/dist/gs/internal/abi/index.js +10 -0
- package/dist/gs/internal/abi/index.js.map +1 -1
- package/dist/gs/internal/bytealg/index.d.ts +2 -0
- package/dist/gs/internal/bytealg/index.js +14 -0
- package/dist/gs/internal/bytealg/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.d.ts +8 -2
- package/dist/gs/internal/byteorder/index.js +56 -25
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/godebug/index.d.ts +12 -0
- package/dist/gs/internal/godebug/index.js +30 -0
- package/dist/gs/internal/godebug/index.js.map +1 -0
- package/dist/gs/io/fs/index.d.ts +1 -0
- package/dist/gs/io/fs/index.js +1 -0
- package/dist/gs/io/fs/index.js.map +1 -1
- package/dist/gs/io/fs/readlink.d.ts +8 -0
- package/dist/gs/io/fs/readlink.js +64 -0
- package/dist/gs/io/fs/readlink.js.map +1 -0
- package/dist/gs/io/fs/walk.d.ts +3 -3
- package/dist/gs/io/fs/walk.js +7 -7
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.d.ts +40 -6
- package/dist/gs/io/io.js +151 -26
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/maps/iter.d.ts +3 -3
- package/dist/gs/maps/iter.js +3 -3
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.d.ts +2 -2
- package/dist/gs/maps/maps.js +1 -1
- package/dist/gs/maps/maps.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +13 -4
- package/dist/gs/math/bits/index.js +66 -34
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/math/const.gs.d.ts +5 -5
- package/dist/gs/math/const.gs.js +4 -4
- package/dist/gs/math/const.gs.js.map +1 -1
- package/dist/gs/mime/index.d.ts +1 -0
- package/dist/gs/mime/index.js +50 -0
- package/dist/gs/mime/index.js.map +1 -0
- package/dist/gs/net/http/httptest/index.d.ts +11 -0
- package/dist/gs/net/http/httptest/index.js +21 -0
- package/dist/gs/net/http/httptest/index.js.map +1 -0
- package/dist/gs/net/http/index.d.ts +27 -0
- package/dist/gs/net/http/index.js +61 -0
- package/dist/gs/net/http/index.js.map +1 -0
- package/dist/gs/os/dir_unix.gs.js +2 -2
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js +165 -3
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.d.ts +3 -1
- package/dist/gs/path/filepath/path.js +133 -4
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/path/path.d.ts +4 -1
- package/dist/gs/path/path.js +16 -4
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +1 -1
- package/dist/gs/reflect/index.js +1 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +3 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +7 -4
- package/dist/gs/reflect/type.js +148 -7
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/runtime/debug/index.d.ts +2 -0
- package/dist/gs/runtime/debug/index.js +8 -0
- package/dist/gs/runtime/debug/index.js.map +1 -0
- package/dist/gs/runtime/runtime.d.ts +35 -3
- package/dist/gs/runtime/runtime.js +72 -0
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +24 -5
- package/dist/gs/slices/slices.js +214 -5
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/slice.gs.d.ts +3 -3
- package/dist/gs/sort/slice.gs.js +6 -6
- package/dist/gs/sort/slice.gs.js.map +1 -1
- package/dist/gs/sort/sort.gs.d.ts +4 -4
- package/dist/gs/sort/sort.gs.js +11 -8
- package/dist/gs/sort/sort.gs.js.map +1 -1
- package/dist/gs/strings/builder.d.ts +1 -1
- package/dist/gs/strings/builder.js +3 -2
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
- package/dist/gs/sync/atomic/type.gs.js +0 -2
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -0
- package/dist/gs/sync/sync.js +27 -0
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/constants.d.ts +36 -24
- package/dist/gs/syscall/constants.js +12 -0
- package/dist/gs/syscall/constants.js.map +1 -1
- package/dist/gs/syscall/errors.d.ts +2 -0
- package/dist/gs/syscall/errors.js +8 -0
- package/dist/gs/syscall/errors.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +43 -0
- package/dist/gs/syscall/fs.js +102 -0
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/syscall/js/index.d.ts +90 -0
- package/dist/gs/syscall/js/index.js +375 -0
- package/dist/gs/syscall/js/index.js.map +1 -0
- package/dist/gs/syscall/types.d.ts +22 -0
- package/dist/gs/syscall/types.js +45 -1
- package/dist/gs/syscall/types.js.map +1 -1
- package/dist/gs/testing/index.d.ts +1 -0
- package/dist/gs/testing/index.js +2 -0
- package/dist/gs/testing/index.js.map +1 -0
- package/dist/gs/testing/testing.d.ts +77 -0
- package/dist/gs/testing/testing.js +301 -0
- package/dist/gs/testing/testing.js.map +1 -0
- package/dist/gs/time/time.d.ts +41 -4
- package/dist/gs/time/time.js +205 -36
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.d.ts +23 -1
- package/dist/gs/unicode/unicode.js +79 -10
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
- package/dist/gs/unicode/utf8/utf8.js +24 -11
- package/dist/gs/unicode/utf8/utf8.js.map +1 -1
- package/dist/gs/unique/index.d.ts +11 -0
- package/dist/gs/unique/index.js +71 -0
- package/dist/gs/unique/index.js.map +1 -0
- package/go.sum +9 -0
- package/gs/builtin/builtin.ts +239 -8
- package/gs/builtin/channel.ts +22 -0
- package/gs/builtin/runtime-contract.test.ts +126 -0
- package/gs/builtin/slice.ts +259 -50
- package/gs/builtin/type.ts +109 -34
- package/gs/builtin/varRef.ts +38 -1
- package/gs/bytes/buffer.gs.ts +48 -44
- package/gs/bytes/meta.json +8 -3
- package/gs/bytes/reader.gs.ts +20 -19
- package/gs/context/context.test.ts +41 -0
- package/gs/context/context.ts +22 -26
- package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
- package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
- package/gs/embed/index.ts +20 -0
- package/gs/embed/meta.json +5 -0
- package/gs/encoding/json/index.test.ts +15 -1
- package/gs/encoding/json/index.ts +24 -0
- package/gs/errors/errors.test.ts +82 -0
- package/gs/errors/errors.ts +104 -0
- package/gs/fmt/fmt.ts +56 -16
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +73 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +297 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +159 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1005 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +719 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +40 -0
- package/gs/github.com/klauspost/compress/internal/le/index.test.ts +36 -0
- package/gs/github.com/klauspost/compress/internal/le/index.ts +114 -0
- package/gs/go/internal/scannerhooks/index.test.ts +14 -0
- package/gs/go/internal/scannerhooks/index.ts +9 -0
- package/gs/go/scanner/index.test.ts +22 -0
- package/gs/go/scanner/index.ts +47 -0
- package/gs/go/token/index.test.ts +47 -1
- package/gs/go/token/index.ts +570 -4
- package/gs/internal/abi/index.test.ts +18 -0
- package/gs/internal/abi/index.ts +14 -0
- package/gs/internal/bytealg/index.test.ts +18 -0
- package/gs/internal/bytealg/index.ts +16 -0
- package/gs/internal/byteorder/index.test.ts +39 -0
- package/gs/internal/byteorder/index.ts +100 -27
- package/gs/internal/godebug/index.test.ts +16 -0
- package/gs/internal/godebug/index.ts +35 -0
- package/gs/io/fs/index.ts +1 -0
- package/gs/io/fs/meta.json +5 -0
- package/gs/io/fs/readlink.test.ts +43 -0
- package/gs/io/fs/readlink.ts +77 -0
- package/gs/io/fs/walk.test.ts +61 -0
- package/gs/io/fs/walk.ts +9 -9
- package/gs/io/io.ts +174 -31
- package/gs/io/meta.json +10 -2
- package/gs/maps/iter.ts +12 -6
- package/gs/maps/maps.ts +8 -6
- package/gs/math/bits/index.ts +103 -47
- package/gs/math/const.gs.test.ts +11 -5
- package/gs/math/const.gs.ts +5 -6
- package/gs/mime/index.ts +54 -0
- package/gs/net/http/httptest/index.ts +25 -0
- package/gs/net/http/index.test.ts +20 -0
- package/gs/net/http/index.ts +81 -0
- package/gs/os/dir_unix.gs.ts +2 -3
- package/gs/os/types_js.gs.ts +2 -2
- package/gs/path/filepath/match.test.ts +31 -12
- package/gs/path/filepath/match.ts +178 -3
- package/gs/path/filepath/path.test.ts +25 -0
- package/gs/path/filepath/path.ts +159 -5
- package/gs/path/path.ts +20 -5
- package/gs/reflect/index.ts +1 -0
- package/gs/reflect/map.test.ts +19 -0
- package/gs/reflect/map.ts +4 -0
- package/gs/reflect/type.ts +197 -17
- package/gs/runtime/debug/index.test.ts +24 -0
- package/gs/runtime/debug/index.ts +8 -0
- package/gs/runtime/runtime.test.ts +19 -0
- package/gs/runtime/runtime.ts +98 -3
- package/gs/slices/slices.test.ts +94 -0
- package/gs/slices/slices.ts +245 -5
- package/gs/sort/meta.json +7 -0
- package/gs/sort/slice.gs.ts +16 -7
- package/gs/sort/sort.gs.ts +16 -13
- package/gs/strings/builder.ts +4 -3
- package/gs/sync/atomic/type.gs.ts +13 -14
- package/gs/sync/meta.json +3 -1
- package/gs/sync/sync.test.ts +13 -1
- package/gs/sync/sync.ts +27 -0
- package/gs/syscall/constants.ts +39 -24
- package/gs/syscall/errors.ts +10 -0
- package/gs/syscall/fs.ts +195 -0
- package/gs/syscall/js/index.ts +458 -0
- package/gs/syscall/js/meta.json +4 -0
- package/gs/syscall/net.test.ts +85 -0
- package/gs/syscall/types.ts +56 -0
- package/gs/testing/index.ts +1 -0
- package/gs/testing/meta.json +5 -0
- package/gs/testing/testing.test.ts +90 -0
- package/gs/testing/testing.ts +382 -0
- package/gs/time/time.test.ts +106 -0
- package/gs/time/time.ts +278 -57
- package/gs/unicode/unicode.test.ts +25 -0
- package/gs/unicode/unicode.ts +119 -9
- package/gs/unicode/utf8/utf8.test.ts +13 -0
- package/gs/unicode/utf8/utf8.ts +28 -16
- package/gs/unique/index.ts +91 -0
- package/package.json +2 -1
package/gs/builtin/type.ts
CHANGED
|
@@ -44,6 +44,7 @@ export interface MethodSignature {
|
|
|
44
44
|
*/
|
|
45
45
|
export interface StructFieldInfo {
|
|
46
46
|
type: TypeInfo | string // The field's type
|
|
47
|
+
name?: string // The Go field name when it differs from the TypeScript key.
|
|
47
48
|
tag?: string // The struct field tag (e.g., `json:"name,omitempty"`)
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -233,6 +234,13 @@ export const registerStructType = (
|
|
|
233
234
|
return typeInfo
|
|
234
235
|
}
|
|
235
236
|
|
|
237
|
+
function resolveZeroValue<T>(zeroValue: any): T {
|
|
238
|
+
if (typeof zeroValue === 'function') {
|
|
239
|
+
return zeroValue() as T
|
|
240
|
+
}
|
|
241
|
+
return zeroValue as T
|
|
242
|
+
}
|
|
243
|
+
|
|
236
244
|
/**
|
|
237
245
|
* Registers an interface type with the runtime type system.
|
|
238
246
|
*
|
|
@@ -500,13 +508,9 @@ function matchesStructType(value: any, info: TypeInfo): boolean {
|
|
|
500
508
|
|
|
501
509
|
if (fieldsExist && sameFieldCount && allFieldsInStruct) {
|
|
502
510
|
return Object.entries(info.fields).every(([fieldName, fieldType]) => {
|
|
503
|
-
const fieldTypeInfo =
|
|
504
|
-
? fieldType.type
|
|
505
|
-
|
|
506
|
-
return matchesType(
|
|
507
|
-
value[fieldName],
|
|
508
|
-
normalizeTypeInfo(fieldTypeInfo),
|
|
509
|
-
)
|
|
511
|
+
const fieldTypeInfo =
|
|
512
|
+
isStructFieldInfo(fieldType) ? fieldType.type : fieldType
|
|
513
|
+
return matchesType(value[fieldName], normalizeTypeInfo(fieldTypeInfo))
|
|
510
514
|
})
|
|
511
515
|
}
|
|
512
516
|
|
|
@@ -667,9 +671,15 @@ function matchesMapType(value: any, info: TypeInfo): boolean {
|
|
|
667
671
|
*/
|
|
668
672
|
function matchesArrayOrSliceType(value: any, info: TypeInfo): boolean {
|
|
669
673
|
// For slices and arrays, check if the value is an array and sample element types
|
|
670
|
-
if (!Array.isArray(value)) return false
|
|
671
674
|
if (!isArrayTypeInfo(info) && !isSliceTypeInfo(info)) return false
|
|
672
675
|
|
|
676
|
+
if (value instanceof Uint8Array) {
|
|
677
|
+
if (isArrayTypeInfo(info) && value.length !== info.length) return false
|
|
678
|
+
return isNumberElementType(info.elemType)
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
if (!Array.isArray(value)) return false
|
|
682
|
+
|
|
673
683
|
if (info.elemType) {
|
|
674
684
|
const arr = value as any[]
|
|
675
685
|
if (arr.length === 0) return true // Empty array matches any array type
|
|
@@ -690,6 +700,21 @@ function matchesArrayOrSliceType(value: any, info: TypeInfo): boolean {
|
|
|
690
700
|
return true
|
|
691
701
|
}
|
|
692
702
|
|
|
703
|
+
function isNumberElementType(typeInfo: string | TypeInfo | undefined): boolean {
|
|
704
|
+
if (typeInfo === undefined) return true
|
|
705
|
+
const info = normalizeTypeInfo(typeInfo)
|
|
706
|
+
return (
|
|
707
|
+
info.kind === TypeKind.Basic &&
|
|
708
|
+
(info.name === undefined ||
|
|
709
|
+
info.name === 'number' ||
|
|
710
|
+
info.name === 'int' ||
|
|
711
|
+
info.name === 'uint' ||
|
|
712
|
+
info.name === 'uint8' ||
|
|
713
|
+
info.name === 'byte' ||
|
|
714
|
+
info.name === 'float64')
|
|
715
|
+
)
|
|
716
|
+
}
|
|
717
|
+
|
|
693
718
|
// Symbol used to mark struct instances that represent values (not pointers)
|
|
694
719
|
const STRUCT_VALUE_MARKER = Symbol('structValue')
|
|
695
720
|
|
|
@@ -701,6 +726,20 @@ export function markAsStructValue<T>(value: T): T {
|
|
|
701
726
|
return value
|
|
702
727
|
}
|
|
703
728
|
|
|
729
|
+
export function cloneStructValue<T>(value: T): T {
|
|
730
|
+
const cloneable = value as T & {
|
|
731
|
+
__goscriptClone?: () => T
|
|
732
|
+
clone?: () => T
|
|
733
|
+
}
|
|
734
|
+
if (typeof cloneable.__goscriptClone === 'function') {
|
|
735
|
+
return cloneable.__goscriptClone()
|
|
736
|
+
}
|
|
737
|
+
if (typeof cloneable.clone === 'function') {
|
|
738
|
+
return cloneable.clone()
|
|
739
|
+
}
|
|
740
|
+
throw new Error('runtime error: value is not cloneable')
|
|
741
|
+
}
|
|
742
|
+
|
|
704
743
|
// Check if a struct instance is marked as a value
|
|
705
744
|
function isMarkedAsStructValue(value: any): boolean {
|
|
706
745
|
return (
|
|
@@ -729,6 +768,10 @@ function matchesPointerType(value: any, info: TypeInfo): boolean {
|
|
|
729
768
|
|
|
730
769
|
if (!isPointerTypeInfo(info)) return false
|
|
731
770
|
|
|
771
|
+
if (typeof value.__goType === 'string') {
|
|
772
|
+
return compareTypeStringWithTypeInfo(value.__goType, info)
|
|
773
|
+
}
|
|
774
|
+
|
|
732
775
|
if (!info.elemType) return false
|
|
733
776
|
|
|
734
777
|
let elem = info.elemType
|
|
@@ -854,6 +897,13 @@ function matchesType(value: any, info: TypeInfo): boolean {
|
|
|
854
897
|
if (value === null || value === undefined) {
|
|
855
898
|
return false
|
|
856
899
|
}
|
|
900
|
+
if (
|
|
901
|
+
typeof value === 'object' &&
|
|
902
|
+
typeof value.__goType === 'string' &&
|
|
903
|
+
value.__goType === info.name
|
|
904
|
+
) {
|
|
905
|
+
return true
|
|
906
|
+
}
|
|
857
907
|
|
|
858
908
|
switch (info.kind) {
|
|
859
909
|
case TypeKind.Basic:
|
|
@@ -1011,7 +1061,10 @@ export function typeAssert<T>(
|
|
|
1011
1061
|
|
|
1012
1062
|
// Handle typed nil pointers (created by typedNil() for conversions like (*T)(nil))
|
|
1013
1063
|
if (typeof value === 'object' && value !== null && value.__isTypedNil) {
|
|
1014
|
-
if (
|
|
1064
|
+
if (
|
|
1065
|
+
isInterfaceTypeInfo(normalizedType) &&
|
|
1066
|
+
matchesInterfaceType(value, normalizedType)
|
|
1067
|
+
) {
|
|
1015
1068
|
return { value: value as T, ok: true }
|
|
1016
1069
|
}
|
|
1017
1070
|
// For typed nils, we need to compare the stored type with the expected type
|
|
@@ -1029,6 +1082,17 @@ export function typeAssert<T>(
|
|
|
1029
1082
|
if (isPointerTypeInfo(normalizedType) && value === null) {
|
|
1030
1083
|
return { value: null as unknown as T, ok: false }
|
|
1031
1084
|
}
|
|
1085
|
+
if (
|
|
1086
|
+
typeof value === 'object' &&
|
|
1087
|
+
value !== null &&
|
|
1088
|
+
typeof value.__goType === 'string' &&
|
|
1089
|
+
value.__goType === normalizedType.name
|
|
1090
|
+
) {
|
|
1091
|
+
if ('__goValue' in value) {
|
|
1092
|
+
return { value: value.__goValue as T, ok: true }
|
|
1093
|
+
}
|
|
1094
|
+
return { value: value as T, ok: true }
|
|
1095
|
+
}
|
|
1032
1096
|
|
|
1033
1097
|
// Removed struct matching logic - struct types should use nominal matching
|
|
1034
1098
|
// via matchesStructType in matchesType, not structural matching here
|
|
@@ -1040,9 +1104,9 @@ export function typeAssert<T>(
|
|
|
1040
1104
|
) {
|
|
1041
1105
|
if (normalizedType.keyType || normalizedType.elemType) {
|
|
1042
1106
|
const entries =
|
|
1043
|
-
value instanceof Map
|
|
1044
|
-
|
|
1045
|
-
|
|
1107
|
+
value instanceof Map ?
|
|
1108
|
+
Array.from(value.entries())
|
|
1109
|
+
: Object.entries(value)
|
|
1046
1110
|
|
|
1047
1111
|
if (entries.length === 0) {
|
|
1048
1112
|
return { value: value as T, ok: true }
|
|
@@ -1080,17 +1144,6 @@ export function typeAssert<T>(
|
|
|
1080
1144
|
|
|
1081
1145
|
const matches = matchesType(value, normalizedType)
|
|
1082
1146
|
if (matches) {
|
|
1083
|
-
// Special handling for pointer type assertions:
|
|
1084
|
-
// If the value is a VarRef and we're asserting to a pointer type,
|
|
1085
|
-
// return the inner value (value.value), not the VarRef object itself
|
|
1086
|
-
if (
|
|
1087
|
-
isPointerTypeInfo(normalizedType) &&
|
|
1088
|
-
typeof value === 'object' &&
|
|
1089
|
-
value !== null &&
|
|
1090
|
-
'value' in value
|
|
1091
|
-
) {
|
|
1092
|
-
return { value: value.value as T, ok: true }
|
|
1093
|
-
}
|
|
1094
1147
|
return { value: value as T, ok: true }
|
|
1095
1148
|
}
|
|
1096
1149
|
|
|
@@ -1099,10 +1152,10 @@ export function typeAssert<T>(
|
|
|
1099
1152
|
if (typeof typeInfo === 'string') {
|
|
1100
1153
|
const registeredType = typeRegistry.get(typeInfo)
|
|
1101
1154
|
if (registeredType && registeredType.zeroValue !== undefined) {
|
|
1102
|
-
return { value: registeredType.zeroValue
|
|
1155
|
+
return { value: resolveZeroValue<T>(registeredType.zeroValue), ok: false }
|
|
1103
1156
|
}
|
|
1104
1157
|
} else if (normalizedType.zeroValue !== undefined) {
|
|
1105
|
-
return { value: normalizedType.zeroValue
|
|
1158
|
+
return { value: resolveZeroValue<T>(normalizedType.zeroValue), ok: false }
|
|
1106
1159
|
}
|
|
1107
1160
|
|
|
1108
1161
|
return { value: null as unknown as T, ok: false }
|
|
@@ -1166,7 +1219,7 @@ export function is(value: any, typeInfo: string | TypeInfo): boolean {
|
|
|
1166
1219
|
*/
|
|
1167
1220
|
export interface TypeSwitchCase {
|
|
1168
1221
|
types: (string | TypeInfo)[] // Array of types for this case (e.g., case int, string:)
|
|
1169
|
-
body: (value?: any) =>
|
|
1222
|
+
body: (value?: any) => any // Function representing the case body. 'value' is the asserted value if applicable.
|
|
1170
1223
|
}
|
|
1171
1224
|
|
|
1172
1225
|
/**
|
|
@@ -1180,16 +1233,15 @@ export interface TypeSwitchCase {
|
|
|
1180
1233
|
export function typeSwitch(
|
|
1181
1234
|
value: any,
|
|
1182
1235
|
cases: TypeSwitchCase[],
|
|
1183
|
-
defaultCase?: () =>
|
|
1184
|
-
):
|
|
1236
|
+
defaultCase?: () => any,
|
|
1237
|
+
): any {
|
|
1185
1238
|
for (const caseObj of cases) {
|
|
1186
1239
|
// For cases with multiple types (case T1, T2:), use $.is
|
|
1187
1240
|
if (caseObj.types.length > 1) {
|
|
1188
1241
|
const matchesAny = caseObj.types.some((typeInfo) => is(value, typeInfo))
|
|
1189
1242
|
if (matchesAny) {
|
|
1190
1243
|
// For multi-type cases, the case variable (if any) gets the original value
|
|
1191
|
-
caseObj.body(value)
|
|
1192
|
-
return // Found a match, exit switch
|
|
1244
|
+
return caseObj.body(value)
|
|
1193
1245
|
}
|
|
1194
1246
|
} else if (caseObj.types.length === 1) {
|
|
1195
1247
|
// For single-type cases (case T:), use $.typeAssert to get the typed value and ok status
|
|
@@ -1197,9 +1249,7 @@ export function typeSwitch(
|
|
|
1197
1249
|
const { value: assertedValue, ok } = typeAssert(value, typeInfo)
|
|
1198
1250
|
if (ok) {
|
|
1199
1251
|
// Pass the asserted value to the case body function
|
|
1200
|
-
caseObj.body(assertedValue)
|
|
1201
|
-
|
|
1202
|
-
return // Found a match, exit switch
|
|
1252
|
+
return caseObj.body(assertedValue)
|
|
1203
1253
|
}
|
|
1204
1254
|
}
|
|
1205
1255
|
// Note: Cases with 0 types are not valid in Go type switches
|
|
@@ -1207,7 +1257,7 @@ export function typeSwitch(
|
|
|
1207
1257
|
|
|
1208
1258
|
// If no case matched and a default case exists, execute it
|
|
1209
1259
|
if (defaultCase) {
|
|
1210
|
-
defaultCase()
|
|
1260
|
+
return defaultCase()
|
|
1211
1261
|
}
|
|
1212
1262
|
}
|
|
1213
1263
|
|
|
@@ -1228,6 +1278,13 @@ export function typedNil(typeName: string): any {
|
|
|
1228
1278
|
|
|
1229
1279
|
export function interfaceValue<T>(value: unknown, typeName: string): T {
|
|
1230
1280
|
if (value !== null && value !== undefined) {
|
|
1281
|
+
if (typeof value === 'object') {
|
|
1282
|
+
Object.defineProperty(value, '__goType', {
|
|
1283
|
+
value: typeName,
|
|
1284
|
+
writable: true,
|
|
1285
|
+
configurable: true,
|
|
1286
|
+
})
|
|
1287
|
+
}
|
|
1231
1288
|
return value as T
|
|
1232
1289
|
}
|
|
1233
1290
|
|
|
@@ -1255,6 +1312,24 @@ export function interfaceValue<T>(value: unknown, typeName: string): T {
|
|
|
1255
1312
|
return nilValue as T
|
|
1256
1313
|
}
|
|
1257
1314
|
|
|
1315
|
+
export function namedValueInterfaceValue<T>(
|
|
1316
|
+
value: unknown,
|
|
1317
|
+
typeName: string,
|
|
1318
|
+
methods: Record<string, (receiver: any, ...args: any[]) => any>,
|
|
1319
|
+
): T {
|
|
1320
|
+
const boxed: any = {
|
|
1321
|
+
__goType: typeName,
|
|
1322
|
+
__goValue: value,
|
|
1323
|
+
valueOf: () => value,
|
|
1324
|
+
toString: () => String(value),
|
|
1325
|
+
[Symbol.toPrimitive]: () => value as any,
|
|
1326
|
+
}
|
|
1327
|
+
for (const [name, method] of Object.entries(methods)) {
|
|
1328
|
+
boxed[name] = (...args: any[]) => method(value, ...args)
|
|
1329
|
+
}
|
|
1330
|
+
return boxed as T
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1258
1333
|
export function namedFunction<T>(fn: T, typeName: string): T {
|
|
1259
1334
|
if (typeof fn !== 'function') {
|
|
1260
1335
|
return fn
|
package/gs/builtin/varRef.ts
CHANGED
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
* var myVariable int // variable referenced
|
|
6
6
|
* myOtherVar := &myVariable
|
|
7
7
|
*/
|
|
8
|
-
export type VarRef<T> = {
|
|
8
|
+
export type VarRef<T> = {
|
|
9
|
+
value: T
|
|
10
|
+
__isVarRef?: true
|
|
11
|
+
__goType?: string
|
|
12
|
+
__goAddress?: () => number
|
|
13
|
+
}
|
|
9
14
|
|
|
10
15
|
/** Wrap a non-null T in a variable reference. */
|
|
11
16
|
export function varRef<T>(v: T): VarRef<T> {
|
|
@@ -15,6 +20,22 @@ export function varRef<T>(v: T): VarRef<T> {
|
|
|
15
20
|
return { value: v, __isVarRef: true }
|
|
16
21
|
}
|
|
17
22
|
|
|
23
|
+
/** Create a variable reference to an object field. */
|
|
24
|
+
export function fieldRef<T extends object, K extends keyof T>(
|
|
25
|
+
target: T,
|
|
26
|
+
key: K,
|
|
27
|
+
): VarRef<T[K]> {
|
|
28
|
+
return {
|
|
29
|
+
get value(): T[K] {
|
|
30
|
+
return target[key]
|
|
31
|
+
},
|
|
32
|
+
set value(value: T[K]) {
|
|
33
|
+
target[key] = value
|
|
34
|
+
},
|
|
35
|
+
__isVarRef: true,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
18
39
|
/** Check if a value is a VarRef (pointer) */
|
|
19
40
|
export function isVarRef(v: unknown): v is VarRef<unknown> {
|
|
20
41
|
return v !== null && typeof v === 'object' && (v as any).__isVarRef === true
|
|
@@ -29,3 +50,19 @@ export function unref<T>(b: VarRef<T>): T {
|
|
|
29
50
|
}
|
|
30
51
|
return b.value
|
|
31
52
|
}
|
|
53
|
+
|
|
54
|
+
export function unsupportedPointerRef<T>(_value: unknown): VarRef<T> {
|
|
55
|
+
return {
|
|
56
|
+
get value(): T {
|
|
57
|
+
throw new Error(
|
|
58
|
+
'unsafe pointer dereference is not supported in JavaScript/TypeScript',
|
|
59
|
+
)
|
|
60
|
+
},
|
|
61
|
+
set value(_value: T) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
'unsafe pointer dereference is not supported in JavaScript/TypeScript',
|
|
64
|
+
)
|
|
65
|
+
},
|
|
66
|
+
__isVarRef: true,
|
|
67
|
+
}
|
|
68
|
+
}
|
package/gs/bytes/buffer.gs.ts
CHANGED
|
@@ -269,28 +269,30 @@ export class Buffer {
|
|
|
269
269
|
// error except io.EOF encountered during the read is also returned. If the
|
|
270
270
|
// buffer becomes too large, ReadFrom will panic with [ErrTooLarge].
|
|
271
271
|
public ReadFrom(r: io.Reader): [number, $.GoError] {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
272
|
+
return (async (): Promise<[number, $.GoError]> => {
|
|
273
|
+
const b = this
|
|
274
|
+
b.lastRead = 0
|
|
275
|
+
let n = 0
|
|
276
|
+
for (; ; ) {
|
|
277
|
+
let i = b.grow(512)
|
|
278
|
+
b.buf = $.goSlice(b.buf, undefined, i)
|
|
279
|
+
let [m, e] = await (r!.Read($.bytesToUint8Array($.goSlice(b.buf, i, $.cap(b.buf)))) as any)
|
|
280
|
+
if (m < 0) {
|
|
281
|
+
$.panic(errNegativeRead)
|
|
282
|
+
}
|
|
282
283
|
|
|
283
|
-
|
|
284
|
-
|
|
284
|
+
b.buf = $.goSlice(b.buf, undefined, i + m)
|
|
285
|
+
n += (m as number)
|
|
285
286
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
287
|
+
// e is EOF, so return nil explicitly
|
|
288
|
+
if (e == io.EOF) {
|
|
289
|
+
return [n, null]
|
|
290
|
+
}
|
|
291
|
+
if (e != null) {
|
|
292
|
+
return [n, e]
|
|
293
|
+
}
|
|
292
294
|
}
|
|
293
|
-
}
|
|
295
|
+
})() as any
|
|
294
296
|
}
|
|
295
297
|
|
|
296
298
|
// WriteTo writes data to w until the buffer is drained or an error occurs.
|
|
@@ -298,30 +300,32 @@ export class Buffer {
|
|
|
298
300
|
// int, but it is int64 to match the [io.WriterTo] interface. Any error
|
|
299
301
|
// encountered during the write is also returned.
|
|
300
302
|
public WriteTo(w: io.Writer): [number, $.GoError] {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
303
|
+
return (async (): Promise<[number, $.GoError]> => {
|
|
304
|
+
const b = this
|
|
305
|
+
b.lastRead = 0
|
|
306
|
+
let n = 0
|
|
307
|
+
{
|
|
308
|
+
let nBytes = b.Len()
|
|
309
|
+
if (nBytes > 0) {
|
|
310
|
+
let [m, e] = await (w!.Write($.bytesToUint8Array($.goSlice(b.buf, b.off, undefined))) as any)
|
|
311
|
+
if (m > nBytes) {
|
|
312
|
+
$.panic("bytes.Buffer.WriteTo: invalid Write count")
|
|
313
|
+
}
|
|
314
|
+
b.off += m
|
|
315
|
+
n = (m as number)
|
|
316
|
+
if (e != null) {
|
|
317
|
+
return [n, e]
|
|
318
|
+
}
|
|
319
|
+
// all bytes should have been written, by definition of
|
|
320
|
+
// Write method in io.Writer
|
|
321
|
+
if (m != nBytes) {
|
|
322
|
+
return [n, io.ErrShortWrite]
|
|
323
|
+
}
|
|
320
324
|
}
|
|
321
325
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
326
|
+
b.Reset()
|
|
327
|
+
return [n, null]
|
|
328
|
+
})() as any
|
|
325
329
|
}
|
|
326
330
|
|
|
327
331
|
// WriteByte appends the byte c to the buffer, growing the buffer as needed.
|
|
@@ -373,7 +377,7 @@ export class Buffer {
|
|
|
373
377
|
}
|
|
374
378
|
return [0, io.EOF]
|
|
375
379
|
}
|
|
376
|
-
const n = $.copy(
|
|
380
|
+
const n = $.copy(p, $.goSlice(b.buf, b.off, undefined))
|
|
377
381
|
b.off += n
|
|
378
382
|
if (n > 0) {
|
|
379
383
|
b.lastRead = -1
|
|
@@ -603,8 +607,8 @@ export function growSlice(b: $.Bytes, n: number): $.Bytes {
|
|
|
603
607
|
// we could rely purely on append to determine the growth rate.
|
|
604
608
|
c = 2 * $.cap(b)
|
|
605
609
|
}
|
|
606
|
-
let b2 = $.
|
|
607
|
-
let i = $.copy(
|
|
610
|
+
let b2 = $.makeSlice<number>(c, c, 'byte')
|
|
611
|
+
let i = $.copy(b2, b)
|
|
608
612
|
return $.goSlice(b2, undefined, i)
|
|
609
613
|
}
|
|
610
614
|
|
package/gs/bytes/meta.json
CHANGED
package/gs/bytes/reader.gs.ts
CHANGED
|
@@ -80,7 +80,7 @@ export class Reader {
|
|
|
80
80
|
return [0, io.EOF]
|
|
81
81
|
}
|
|
82
82
|
r.prevRune = -1
|
|
83
|
-
const n = $.copy(
|
|
83
|
+
const n = $.copy(b, $.goSlice(r.s, r.i, undefined))
|
|
84
84
|
r.i += (n as number)
|
|
85
85
|
return [n, null]
|
|
86
86
|
}
|
|
@@ -94,7 +94,7 @@ export class Reader {
|
|
|
94
94
|
if (off >= ($.len(r.s) as number)) {
|
|
95
95
|
return [0, io.EOF]
|
|
96
96
|
}
|
|
97
|
-
const n = $.copy(
|
|
97
|
+
const n = $.copy(b, $.goSlice(r.s, off, undefined))
|
|
98
98
|
let err: $.GoError = null
|
|
99
99
|
if (n < $.len(b)) {
|
|
100
100
|
err = io.EOF
|
|
@@ -187,22 +187,24 @@ export class Reader {
|
|
|
187
187
|
|
|
188
188
|
// WriteTo implements the [io.WriterTo] interface.
|
|
189
189
|
public WriteTo(w: io.Writer): [number, $.GoError] {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
190
|
+
return (async (): Promise<[number, $.GoError]> => {
|
|
191
|
+
const r = this
|
|
192
|
+
r.prevRune = -1
|
|
193
|
+
if (r.i >= ($.len(r.s) as number)) {
|
|
194
|
+
return [0, null]
|
|
195
|
+
}
|
|
196
|
+
const b = $.goSlice(r.s, r.i, undefined)
|
|
197
|
+
const [m, err] = await (w!.Write($.bytesToUint8Array(b)) as any)
|
|
198
|
+
if (m > $.len(b)) {
|
|
199
|
+
$.panic("bytes.Reader.WriteTo: invalid Write count")
|
|
200
|
+
}
|
|
201
|
+
r.i += (m as number)
|
|
202
|
+
const n = (m as number)
|
|
203
|
+
if (m != $.len(b) && err == null) {
|
|
204
|
+
return [n, io.ErrShortWrite]
|
|
205
|
+
}
|
|
206
|
+
return [n, err]
|
|
207
|
+
})() as any
|
|
206
208
|
}
|
|
207
209
|
|
|
208
210
|
// Reset resets the [Reader] to be reading from b.
|
|
@@ -227,4 +229,3 @@ export class Reader {
|
|
|
227
229
|
export function NewReader(b: $.Bytes): Reader {
|
|
228
230
|
return new Reader({s: $.normalizeBytes(b), i: 0, prevRune: -1})
|
|
229
231
|
}
|
|
230
|
-
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { AfterFunc, WithCancel, Background } from './index.js'
|
|
4
|
+
|
|
5
|
+
async function nextMicrotask(): Promise<void> {
|
|
6
|
+
await new Promise<void>((resolve) => queueMicrotask(resolve))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
describe('context override', () => {
|
|
10
|
+
it('runs AfterFunc after cancellation', async () => {
|
|
11
|
+
const [ctx, cancel] = WithCancel(Background())
|
|
12
|
+
let called = false
|
|
13
|
+
|
|
14
|
+
const stop = AfterFunc(ctx, () => {
|
|
15
|
+
called = true
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
cancel?.()
|
|
19
|
+
await nextMicrotask()
|
|
20
|
+
await nextMicrotask()
|
|
21
|
+
|
|
22
|
+
expect(called).toBe(true)
|
|
23
|
+
expect(stop()).toBe(false)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('stops AfterFunc before cancellation', async () => {
|
|
27
|
+
const [ctx, cancel] = WithCancel(Background())
|
|
28
|
+
let called = false
|
|
29
|
+
|
|
30
|
+
const stop = AfterFunc(ctx, () => {
|
|
31
|
+
called = true
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
expect(stop()).toBe(true)
|
|
35
|
+
cancel?.()
|
|
36
|
+
await nextMicrotask()
|
|
37
|
+
await nextMicrotask()
|
|
38
|
+
|
|
39
|
+
expect(called).toBe(false)
|
|
40
|
+
})
|
|
41
|
+
})
|