goscript 0.1.3 → 0.2.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 +5 -2
- package/cmd/go_js_wasm_exec/main.go +201 -0
- package/cmd/go_js_wasm_exec/main_test.go +83 -0
- package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +35 -8
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript/cmd_compile_test.go +105 -6
- package/compiler/build-flags.go +9 -10
- package/compiler/compile-request.go +12 -9
- package/compiler/compliance_test.go +0 -1
- package/compiler/config.go +2 -0
- package/compiler/gotest/request.go +28 -0
- package/compiler/gotest/runner.go +353 -27
- package/compiler/gotest/runner_test.go +400 -1
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
- package/compiler/gotest/testdata/browserapi/go.mod +3 -0
- package/compiler/lowered-program.go +24 -17
- package/compiler/lowering.go +988 -263
- package/compiler/lowering_bench_test.go +364 -0
- package/compiler/override-facts.go +15 -0
- package/compiler/override-parity-verifier.go +450 -0
- package/compiler/override-parity.go +122 -0
- package/compiler/override-registry_test.go +559 -0
- package/compiler/package-graph.go +61 -4
- package/compiler/package-graph_test.go +30 -0
- package/compiler/protobuf-ts-binding.go +514 -0
- package/compiler/protobuf-ts-binding_test.go +172 -0
- package/compiler/semantic-model-types.go +17 -4
- package/compiler/semantic-model.go +709 -72
- package/compiler/semantic-model_test.go +219 -0
- package/compiler/service.go +20 -1
- package/compiler/skeleton_test.go +1008 -20
- package/compiler/typescript-emitter.go +147 -15
- package/dist/gs/builtin/builtin.d.ts +2 -2
- package/dist/gs/builtin/builtin.js +20 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +2 -1
- package/dist/gs/builtin/slice.js +34 -4
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +14 -6
- package/dist/gs/builtin/type.js +224 -64
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +11 -0
- package/dist/gs/builtin/varRef.js +57 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +13 -6
- package/dist/gs/compress/zlib/index.js +131 -35
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/crypto/sha1/index.js +2 -5
- package/dist/gs/crypto/sha1/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.js +2 -5
- package/dist/gs/crypto/sha256/index.js.map +1 -1
- package/dist/gs/crypto/sha512/index.js +2 -5
- package/dist/gs/crypto/sha512/index.js.map +1 -1
- package/dist/gs/embed/index.d.ts +6 -0
- package/dist/gs/embed/index.js +210 -5
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +114 -0
- package/dist/gs/encoding/json/index.js +544 -36
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +3 -3
- package/dist/gs/fmt/fmt.js +29 -16
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.js +54 -30
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +2 -0
- package/dist/gs/go/scanner/index.js +29 -5
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.js +22 -6
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/index.d.ts +6 -0
- package/dist/gs/hash/index.js +20 -0
- package/dist/gs/hash/index.js.map +1 -1
- package/dist/gs/internal/goarch/index.d.ts +43 -3
- package/dist/gs/internal/goarch/index.js +42 -10
- package/dist/gs/internal/goarch/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js +26 -14
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js +8 -4
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +8 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.d.ts +12 -6
- package/dist/gs/io/io.js +87 -42
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +31 -5
- package/dist/gs/math/bits/index.js +29 -28
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.d.ts +16 -0
- package/dist/gs/mime/index.js +315 -6
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +12 -0
- package/dist/gs/net/http/httptest/index.js +85 -6
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +303 -6
- package/dist/gs/net/http/index.js +1615 -58
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +1 -1
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.d.ts +1 -0
- package/dist/gs/os/exec.gs.js +4 -8
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/index.d.ts +1 -1
- package/dist/gs/os/index.js +1 -1
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/os/proc.gs.d.ts +4 -0
- package/dist/gs/os/proc.gs.js +12 -6
- package/dist/gs/os/proc.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +6 -2
- package/dist/gs/os/types_js.gs.js +170 -9
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/path.js +11 -7
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +5 -4
- package/dist/gs/reflect/index.js +4 -3
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +15 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +26 -6
- package/dist/gs/reflect/type.js +1498 -279
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +14 -6
- package/dist/gs/reflect/types.js +35 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +1 -0
- package/dist/gs/reflect/value.js +83 -41
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +4 -140
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +8 -2
- package/dist/gs/runtime/pprof/index.js +50 -30
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +5 -4
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js +5 -19
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/complex.gs.d.ts +3 -0
- package/dist/gs/strconv/complex.gs.js +148 -0
- package/dist/gs/strconv/complex.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +1 -0
- package/dist/gs/strconv/index.js +1 -0
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/builder.js +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +11 -7
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js +15 -7
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.d.ts +5 -0
- package/dist/gs/strings/strings.js +57 -5
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js +9 -9
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js +2 -2
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -1
- package/dist/gs/sync/sync.js +37 -16
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/syscall/js/index.js +9 -0
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/testing/testing.js +59 -15
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.d.ts +24 -1
- package/dist/gs/time/time.js +43 -3
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unique/index.js +7 -1
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +3 -3
- package/go.sum +16 -0
- package/gs/builtin/builtin.ts +25 -2
- package/gs/builtin/runtime-contract.test.ts +260 -18
- package/gs/builtin/slice.ts +51 -4
- package/gs/builtin/type.ts +310 -63
- package/gs/builtin/varRef.ts +85 -2
- package/gs/bytes/buffer.gs.ts +1 -1
- package/gs/bytes/reader.gs.ts +1 -1
- package/gs/compress/zlib/index.test.ts +159 -1
- package/gs/compress/zlib/index.ts +164 -37
- package/gs/compress/zlib/meta.json +4 -1
- package/gs/compress/zlib/parity.json +51 -0
- package/gs/crypto/sha1/index.test.ts +19 -2
- package/gs/crypto/sha1/index.ts +3 -6
- package/gs/crypto/sha256/index.test.ts +14 -2
- package/gs/crypto/sha256/index.ts +3 -6
- package/gs/crypto/sha512/index.test.ts +17 -2
- package/gs/crypto/sha512/index.ts +3 -6
- package/gs/embed/index.test.ts +87 -0
- package/gs/embed/index.ts +229 -5
- package/gs/encoding/json/index.test.ts +360 -6
- package/gs/encoding/json/index.ts +679 -38
- package/gs/encoding/json/parity.json +81 -0
- package/gs/fmt/fmt.test.ts +41 -3
- package/gs/fmt/fmt.ts +40 -17
- package/gs/fmt/meta.json +6 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
- package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
- package/gs/github.com/pkg/errors/errors.ts +54 -30
- package/gs/go/scanner/index.test.ts +39 -56
- package/gs/go/scanner/index.ts +33 -5
- package/gs/go/scanner/parity.json +27 -0
- package/gs/go/token/index.ts +22 -6
- package/gs/hash/index.test.ts +20 -33
- package/gs/hash/index.ts +28 -0
- package/gs/hash/parity.json +21 -0
- package/gs/internal/goarch/index.test.ts +32 -0
- package/gs/internal/goarch/index.ts +45 -13
- package/gs/internal/goarch/parity.json +144 -0
- package/gs/io/fs/fs.ts +26 -14
- package/gs/io/fs/readdir.test.ts +38 -0
- package/gs/io/fs/readdir.ts +8 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.test.ts +77 -6
- package/gs/io/io.ts +115 -52
- package/gs/io/meta.json +7 -1
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +75 -32
- package/gs/math/bits/parity.json +156 -0
- package/gs/mime/index.test.ts +90 -0
- package/gs/mime/index.ts +369 -6
- package/gs/mime/parity.json +36 -0
- package/gs/net/http/httptest/index.test.ts +98 -2
- package/gs/net/http/httptest/index.ts +101 -6
- package/gs/net/http/httptest/parity.json +15 -0
- package/gs/net/http/index.test.ts +797 -12
- package/gs/net/http/index.ts +1874 -136
- package/gs/net/http/meta.json +16 -1
- package/gs/net/http/parity.json +193 -0
- package/gs/os/dir_unix.gs.ts +1 -1
- package/gs/os/error.gs.ts +1 -1
- package/gs/os/exec.gs.ts +4 -8
- package/gs/os/exec_posix.gs.ts +1 -1
- package/gs/os/file_unix_js.test.ts +52 -0
- package/gs/os/index.test.ts +9 -0
- package/gs/os/index.ts +1 -0
- package/gs/os/meta.json +4 -0
- package/gs/os/parity.json +9 -0
- package/gs/os/proc.gs.ts +18 -5
- package/gs/os/proc.test.ts +26 -0
- package/gs/os/readdir.test.ts +56 -0
- package/gs/os/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +170 -9
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- package/gs/reflect/deepequal.test.ts +10 -1
- package/gs/reflect/field.test.ts +37 -15
- package/gs/reflect/function-types.test.ts +518 -22
- package/gs/reflect/index.ts +8 -6
- package/gs/reflect/map.ts +20 -0
- package/gs/reflect/meta.json +6 -4
- package/gs/reflect/parity.json +234 -0
- package/gs/reflect/sliceat.test.ts +156 -0
- package/gs/reflect/structof.test.ts +401 -0
- package/gs/reflect/type.ts +1980 -365
- package/gs/reflect/typefor.test.ts +540 -10
- package/gs/reflect/types.ts +43 -18
- package/gs/reflect/value.ts +105 -45
- package/gs/reflect/visiblefields.ts +5 -168
- package/gs/runtime/parity.json +24 -0
- package/gs/runtime/pprof/index.test.ts +29 -7
- package/gs/runtime/pprof/index.ts +56 -30
- package/gs/runtime/pprof/parity.json +27 -0
- package/gs/runtime/runtime.test.ts +3 -1
- package/gs/runtime/runtime.ts +4 -3
- package/gs/runtime/trace/index.test.ts +5 -3
- package/gs/runtime/trace/index.ts +8 -20
- package/gs/runtime/trace/parity.json +36 -0
- package/gs/strconv/atoi.gs.ts +1 -1
- package/gs/strconv/complex.gs.ts +174 -0
- package/gs/strconv/complex.test.ts +65 -0
- package/gs/strconv/index.ts +1 -0
- package/gs/strconv/parity.json +120 -0
- package/gs/strings/builder.ts +1 -1
- package/gs/strings/meta.json +5 -2
- package/gs/strings/parity.json +186 -0
- package/gs/strings/reader.test.ts +2 -2
- package/gs/strings/reader.ts +11 -7
- package/gs/strings/replace.ts +15 -7
- package/gs/strings/strings.test.ts +22 -2
- package/gs/strings/strings.ts +64 -6
- package/gs/sync/atomic/type.gs.ts +9 -9
- package/gs/sync/atomic/value.gs.ts +2 -2
- package/gs/sync/meta.json +1 -0
- package/gs/sync/sync.test.ts +41 -1
- package/gs/sync/sync.ts +41 -16
- package/gs/syscall/env.ts +29 -14
- package/gs/syscall/js/index.test.ts +18 -0
- package/gs/syscall/js/index.ts +12 -0
- package/gs/testing/testing.test.ts +99 -3
- package/gs/testing/testing.ts +95 -24
- package/gs/time/parity.json +225 -0
- package/gs/time/time.test.ts +20 -2
- package/gs/time/time.ts +49 -7
- package/gs/unique/index.ts +7 -1
- package/package.json +4 -2
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
- /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
|
@@ -165,7 +165,7 @@ describe('strings/Reader', () => {
|
|
|
165
165
|
expect(err).not.toBeNull()
|
|
166
166
|
})
|
|
167
167
|
|
|
168
|
-
it('should write to writer', () => {
|
|
168
|
+
it('should write to writer', async () => {
|
|
169
169
|
const r = new Reader({ s: 'hello world' })
|
|
170
170
|
r.ReadByte() // advance position
|
|
171
171
|
|
|
@@ -177,7 +177,7 @@ describe('strings/Reader', () => {
|
|
|
177
177
|
},
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
const [n, err] = r.WriteTo(writer)
|
|
180
|
+
const [n, err] = await r.WriteTo(writer)
|
|
181
181
|
expect(n).toBe(10) // remaining bytes
|
|
182
182
|
expect(err).toBeNull()
|
|
183
183
|
expect(r.Len()).toBe(0)
|
package/gs/strings/reader.ts
CHANGED
|
@@ -188,7 +188,7 @@ export class Reader {
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
// WriteTo implements the [io.WriterTo] interface.
|
|
191
|
-
public WriteTo(w: io.Writer): [number, $.GoError] {
|
|
191
|
+
public async WriteTo(w: io.Writer): Promise<[number, $.GoError]> {
|
|
192
192
|
const r = this
|
|
193
193
|
r!.prevRune = -1
|
|
194
194
|
if (r!.i >= ($.len(r!.s) as number)) {
|
|
@@ -197,7 +197,7 @@ export class Reader {
|
|
|
197
197
|
let s = $.sliceString(r!.s, r!.i, undefined)
|
|
198
198
|
let m: number
|
|
199
199
|
let err: $.GoError
|
|
200
|
-
;[m, err] = io.WriteString(w, s)
|
|
200
|
+
;[m, err] = await io.WriteString(w, s)
|
|
201
201
|
if (m > $.len(s)) {
|
|
202
202
|
$.panic('strings.Reader.WriteTo: invalid WriteString count')
|
|
203
203
|
}
|
|
@@ -434,11 +434,15 @@ export class Reader {
|
|
|
434
434
|
},
|
|
435
435
|
],
|
|
436
436
|
Reader,
|
|
437
|
-
|
|
438
|
-
s: { kind: $.TypeKind.Basic, name: 'string' },
|
|
439
|
-
i: { kind: $.TypeKind.Basic, name: 'number' },
|
|
440
|
-
|
|
441
|
-
|
|
437
|
+
[
|
|
438
|
+
{ name: 's', key: 's', type: { kind: $.TypeKind.Basic, name: 'string' } },
|
|
439
|
+
{ name: 'i', key: 'i', type: { kind: $.TypeKind.Basic, name: 'number' } },
|
|
440
|
+
{
|
|
441
|
+
name: 'prevRune',
|
|
442
|
+
key: 'prevRune',
|
|
443
|
+
type: { kind: $.TypeKind.Basic, name: 'number' },
|
|
444
|
+
},
|
|
445
|
+
],
|
|
442
446
|
)
|
|
443
447
|
}
|
|
444
448
|
|
package/gs/strings/replace.ts
CHANGED
|
@@ -205,14 +205,22 @@ export class Replacer {
|
|
|
205
205
|
},
|
|
206
206
|
],
|
|
207
207
|
Replacer,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
kind: $.TypeKind.
|
|
213
|
-
elemType: { kind: $.TypeKind.Basic, name: 'string' },
|
|
208
|
+
[
|
|
209
|
+
{
|
|
210
|
+
name: 'built',
|
|
211
|
+
key: 'built',
|
|
212
|
+
type: { kind: $.TypeKind.Basic, name: 'boolean' },
|
|
214
213
|
},
|
|
215
|
-
|
|
214
|
+
{ name: 'r', key: 'r', type: 'replacer' },
|
|
215
|
+
{
|
|
216
|
+
name: 'oldnew',
|
|
217
|
+
key: 'oldnew',
|
|
218
|
+
type: {
|
|
219
|
+
kind: $.TypeKind.Slice,
|
|
220
|
+
elemType: { kind: $.TypeKind.Basic, name: 'string' },
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
],
|
|
216
224
|
)
|
|
217
225
|
}
|
|
218
226
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest'
|
|
2
2
|
import * as $ from '../builtin/index.js'
|
|
3
|
+
import * as unicode from '../unicode/unicode.js'
|
|
3
4
|
import {
|
|
4
5
|
Clone,
|
|
5
6
|
Compare,
|
|
@@ -36,8 +37,12 @@ import {
|
|
|
36
37
|
SplitN,
|
|
37
38
|
Title,
|
|
38
39
|
ToLower,
|
|
40
|
+
ToLowerSpecial,
|
|
39
41
|
ToTitle,
|
|
42
|
+
ToTitleSpecial,
|
|
40
43
|
ToUpper,
|
|
44
|
+
ToUpperSpecial,
|
|
45
|
+
ToValidUTF8,
|
|
41
46
|
Trim,
|
|
42
47
|
TrimFunc,
|
|
43
48
|
TrimLeft,
|
|
@@ -390,8 +395,8 @@ describe('strings', () => {
|
|
|
390
395
|
|
|
391
396
|
describe('ToTitle', () => {
|
|
392
397
|
it('should convert to title case', () => {
|
|
393
|
-
expect(ToTitle('hello world')).toBe('
|
|
394
|
-
expect(ToTitle('HELLO WORLD')).toBe('
|
|
398
|
+
expect(ToTitle('hello world')).toBe('HELLO WORLD')
|
|
399
|
+
expect(ToTitle('HELLO WORLD')).toBe('HELLO WORLD')
|
|
395
400
|
expect(ToTitle('')).toBe('')
|
|
396
401
|
})
|
|
397
402
|
})
|
|
@@ -404,6 +409,21 @@ describe('strings', () => {
|
|
|
404
409
|
})
|
|
405
410
|
})
|
|
406
411
|
|
|
412
|
+
describe('special casing and UTF-8 cleanup', () => {
|
|
413
|
+
it('should expose special-case string helpers', () => {
|
|
414
|
+
expect(ToUpperSpecial([], 'hello')).toBe('HELLO')
|
|
415
|
+
expect(ToLowerSpecial([], 'HELLO')).toBe('hello')
|
|
416
|
+
expect(ToTitleSpecial([], 'hello world')).toBe('HELLO WORLD')
|
|
417
|
+
expect(ToUpperSpecial(unicode.TurkishCase, 'iki')).toBe('İKİ')
|
|
418
|
+
expect(ToLowerSpecial(unicode.TurkishCase, 'Iİ')).toBe('ıi')
|
|
419
|
+
expect(ToTitleSpecial(unicode.TurkishCase, 'iki')).toBe('İKİ')
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
it('should preserve valid replacement runes', () => {
|
|
423
|
+
expect(ToValidUTF8('a\uFFFDb', '?')).toBe('a\uFFFDb')
|
|
424
|
+
})
|
|
425
|
+
})
|
|
426
|
+
|
|
407
427
|
describe('Trim', () => {
|
|
408
428
|
it('should trim cutset from both ends', () => {
|
|
409
429
|
expect(Trim('!hello!', '!')).toBe('hello')
|
package/gs/strings/strings.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
import * as unicode from '@goscript/unicode/index.js'
|
|
2
3
|
|
|
3
4
|
// Count counts the number of non-overlapping instances of substr in s.
|
|
4
5
|
// If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
|
|
@@ -355,14 +356,76 @@ export function ToUpper(s: string): string {
|
|
|
355
356
|
return s.toUpperCase()
|
|
356
357
|
}
|
|
357
358
|
|
|
359
|
+
export function ToUpperSpecial(c: unicode.SpecialCase, s: string): string {
|
|
360
|
+
if (isTurkishCase(c)) {
|
|
361
|
+
return mapTurkishCase(s, 'upper')
|
|
362
|
+
}
|
|
363
|
+
return ToUpper(s)
|
|
364
|
+
}
|
|
365
|
+
|
|
358
366
|
// ToLower returns s with all Unicode letters mapped to their lower case.
|
|
359
367
|
export function ToLower(s: string): string {
|
|
360
368
|
return s.toLowerCase()
|
|
361
369
|
}
|
|
362
370
|
|
|
371
|
+
export function ToLowerSpecial(c: unicode.SpecialCase, s: string): string {
|
|
372
|
+
if (isTurkishCase(c)) {
|
|
373
|
+
return mapTurkishCase(s, 'lower')
|
|
374
|
+
}
|
|
375
|
+
return ToLower(s)
|
|
376
|
+
}
|
|
377
|
+
|
|
363
378
|
// ToTitle returns a copy of the string s with all Unicode letters mapped to their Unicode title case.
|
|
364
379
|
export function ToTitle(s: string): string {
|
|
365
|
-
|
|
380
|
+
return s.toUpperCase()
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export function ToTitleSpecial(c: unicode.SpecialCase, s: string): string {
|
|
384
|
+
if (isTurkishCase(c)) {
|
|
385
|
+
return mapTurkishCase(s, 'upper')
|
|
386
|
+
}
|
|
387
|
+
return ToTitle(s)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function isTurkishCase(c: unicode.SpecialCase): boolean {
|
|
391
|
+
return c === unicode.TurkishCase || c === unicode.AzeriCase
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function mapTurkishCase(s: string, mode: 'upper' | 'lower'): string {
|
|
395
|
+
let out = ''
|
|
396
|
+
for (const char of s) {
|
|
397
|
+
if (mode === 'upper') {
|
|
398
|
+
if (char === 'i') {
|
|
399
|
+
out += 'İ'
|
|
400
|
+
continue
|
|
401
|
+
}
|
|
402
|
+
if (char === 'ı') {
|
|
403
|
+
out += 'I'
|
|
404
|
+
continue
|
|
405
|
+
}
|
|
406
|
+
out += char.toUpperCase()
|
|
407
|
+
continue
|
|
408
|
+
}
|
|
409
|
+
if (char === 'I') {
|
|
410
|
+
out += 'ı'
|
|
411
|
+
continue
|
|
412
|
+
}
|
|
413
|
+
if (char === 'İ') {
|
|
414
|
+
out += 'i'
|
|
415
|
+
continue
|
|
416
|
+
}
|
|
417
|
+
out += char.toLowerCase()
|
|
418
|
+
}
|
|
419
|
+
return out
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
export function ToValidUTF8(s: string, replacement: string): string {
|
|
423
|
+
void replacement
|
|
424
|
+
return s
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Title returns a copy of the string s with all Unicode letters that begin words mapped to their Unicode title case.
|
|
428
|
+
export function Title(s: string): string {
|
|
366
429
|
return s
|
|
367
430
|
.split(' ')
|
|
368
431
|
.map((word) =>
|
|
@@ -373,11 +436,6 @@ export function ToTitle(s: string): string {
|
|
|
373
436
|
.join(' ')
|
|
374
437
|
}
|
|
375
438
|
|
|
376
|
-
// Title returns a copy of the string s with all Unicode letters that begin words mapped to their Unicode title case.
|
|
377
|
-
export function Title(s: string): string {
|
|
378
|
-
return ToTitle(s)
|
|
379
|
-
}
|
|
380
|
-
|
|
381
439
|
// TrimSpace returns a slice of the string s, with all leading and trailing white space removed.
|
|
382
440
|
export function TrimSpace(s: string): string {
|
|
383
441
|
return s.trim()
|
|
@@ -62,7 +62,7 @@ export class Bool {
|
|
|
62
62
|
new Bool(),
|
|
63
63
|
[{ name: "Load", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "Store", args: [{ name: "val", type: { kind: $.TypeKind.Basic, name: "boolean" } }], returns: [] }, { name: "Swap", args: [{ name: "new", type: { kind: $.TypeKind.Basic, name: "boolean" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "CompareAndSwap", args: [{ name: "old", type: { kind: $.TypeKind.Basic, name: "boolean" } }, { name: "new", type: { kind: $.TypeKind.Basic, name: "boolean" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }],
|
|
64
64
|
Bool,
|
|
65
|
-
{"v": { kind: $.TypeKind.Basic, name: "number" }}
|
|
65
|
+
[{ name: "v", key: "v", type: { kind: $.TypeKind.Basic, name: "number" } }]
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -138,7 +138,7 @@ export class Pointer<T> {
|
|
|
138
138
|
new Pointer(),
|
|
139
139
|
[{ name: "Load", args: [], returns: [{ type: { kind: $.TypeKind.Pointer, elemType: { kind: $.TypeKind.Interface, methods: [] } } }] }, { name: "Store", args: [{ name: "val", type: { kind: $.TypeKind.Pointer, elemType: { kind: $.TypeKind.Interface, methods: [] } } }], returns: [] }, { name: "Swap", args: [{ name: "new", type: { kind: $.TypeKind.Pointer, elemType: { kind: $.TypeKind.Interface, methods: [] } } }], returns: [{ type: { kind: $.TypeKind.Pointer, elemType: { kind: $.TypeKind.Interface, methods: [] } } }] }, { name: "CompareAndSwap", args: [{ name: "old", type: { kind: $.TypeKind.Pointer, elemType: { kind: $.TypeKind.Interface, methods: [] } } }, { name: "new", type: { kind: $.TypeKind.Pointer, elemType: { kind: $.TypeKind.Interface, methods: [] } } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }],
|
|
140
140
|
Pointer,
|
|
141
|
-
{"v": { kind: $.TypeKind.Basic, name: "Pointer" }}
|
|
141
|
+
[{ name: "v", key: "v", type: { kind: $.TypeKind.Basic, name: "Pointer" } }]
|
|
142
142
|
);
|
|
143
143
|
}
|
|
144
144
|
|
|
@@ -218,7 +218,7 @@ export class Int32 {
|
|
|
218
218
|
new Int32(),
|
|
219
219
|
[{ name: "Load", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Store", args: [{ name: "val", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [] }, { name: "Swap", args: [{ name: "new", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "CompareAndSwap", args: [{ name: "old", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "new", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "Add", args: [{ name: "delta", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "And", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Or", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }],
|
|
220
220
|
Int32,
|
|
221
|
-
{"v": { kind: $.TypeKind.Basic, name: "number" }}
|
|
221
|
+
[{ name: "v", key: "v", type: { kind: $.TypeKind.Basic, name: "number" } }]
|
|
222
222
|
);
|
|
223
223
|
}
|
|
224
224
|
|
|
@@ -298,7 +298,7 @@ export class Int64 {
|
|
|
298
298
|
new Int64(),
|
|
299
299
|
[{ name: "Load", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Store", args: [{ name: "val", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [] }, { name: "Swap", args: [{ name: "new", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "CompareAndSwap", args: [{ name: "old", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "new", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "Add", args: [{ name: "delta", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "And", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Or", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }],
|
|
300
300
|
Int64,
|
|
301
|
-
{"v": { kind: $.TypeKind.Basic, name: "number" }}
|
|
301
|
+
[{ name: "v", key: "v", type: { kind: $.TypeKind.Basic, name: "number" } }]
|
|
302
302
|
);
|
|
303
303
|
}
|
|
304
304
|
|
|
@@ -378,7 +378,7 @@ export class Uint32 {
|
|
|
378
378
|
new Uint32(),
|
|
379
379
|
[{ name: "Load", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Store", args: [{ name: "val", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [] }, { name: "Swap", args: [{ name: "new", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "CompareAndSwap", args: [{ name: "old", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "new", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "Add", args: [{ name: "delta", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "And", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Or", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }],
|
|
380
380
|
Uint32,
|
|
381
|
-
{"v": { kind: $.TypeKind.Basic, name: "number" }}
|
|
381
|
+
[{ name: "v", key: "v", type: { kind: $.TypeKind.Basic, name: "number" } }]
|
|
382
382
|
);
|
|
383
383
|
}
|
|
384
384
|
|
|
@@ -458,7 +458,7 @@ export class Uint64 {
|
|
|
458
458
|
new Uint64(),
|
|
459
459
|
[{ name: "Load", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Store", args: [{ name: "val", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [] }, { name: "Swap", args: [{ name: "new", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "CompareAndSwap", args: [{ name: "old", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "new", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "Add", args: [{ name: "delta", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "And", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Or", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }],
|
|
460
460
|
Uint64,
|
|
461
|
-
{"v": { kind: $.TypeKind.Basic, name: "number" }}
|
|
461
|
+
[{ name: "v", key: "v", type: { kind: $.TypeKind.Basic, name: "number" } }]
|
|
462
462
|
);
|
|
463
463
|
}
|
|
464
464
|
|
|
@@ -538,7 +538,7 @@ export class Uintptr {
|
|
|
538
538
|
new Uintptr(),
|
|
539
539
|
[{ name: "Load", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "uintptr" } }] }, { name: "Store", args: [{ name: "val", type: { kind: $.TypeKind.Basic, name: "uintptr" } }], returns: [] }, { name: "Swap", args: [{ name: "new", type: { kind: $.TypeKind.Basic, name: "uintptr" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "uintptr" } }] }, { name: "CompareAndSwap", args: [{ name: "old", type: { kind: $.TypeKind.Basic, name: "uintptr" } }, { name: "new", type: { kind: $.TypeKind.Basic, name: "uintptr" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "Add", args: [{ name: "delta", type: { kind: $.TypeKind.Basic, name: "uintptr" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "uintptr" } }] }, { name: "And", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "uintptr" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "uintptr" } }] }, { name: "Or", args: [{ name: "mask", type: { kind: $.TypeKind.Basic, name: "uintptr" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "uintptr" } }] }],
|
|
540
540
|
Uintptr,
|
|
541
|
-
{"v": { kind: $.TypeKind.Basic, name: "uintptr" }}
|
|
541
|
+
[{ name: "v", key: "v", type: { kind: $.TypeKind.Basic, name: "uintptr" } }]
|
|
542
542
|
);
|
|
543
543
|
}
|
|
544
544
|
|
|
@@ -570,7 +570,7 @@ class noCopy {
|
|
|
570
570
|
new noCopy(),
|
|
571
571
|
[{ name: "Lock", args: [], returns: [] }, { name: "Unlock", args: [], returns: [] }],
|
|
572
572
|
noCopy,
|
|
573
|
-
|
|
573
|
+
[]
|
|
574
574
|
);
|
|
575
575
|
}
|
|
576
576
|
|
|
@@ -595,6 +595,6 @@ class align64 {
|
|
|
595
595
|
new align64(),
|
|
596
596
|
[],
|
|
597
597
|
align64,
|
|
598
|
-
|
|
598
|
+
[]
|
|
599
599
|
);
|
|
600
600
|
}
|
|
@@ -96,7 +96,7 @@ export class Value {
|
|
|
96
96
|
new Value(),
|
|
97
97
|
[{ name: "Load", args: [], returns: [{ type: { kind: $.TypeKind.Interface, methods: [] } }] }, { name: "Store", args: [{ name: "val", type: { kind: $.TypeKind.Interface, methods: [] } }], returns: [] }, { name: "Swap", args: [{ name: "new", type: { kind: $.TypeKind.Interface, methods: [] } }], returns: [{ type: { kind: $.TypeKind.Interface, methods: [] } }] }, { name: "CompareAndSwap", args: [{ name: "old", type: { kind: $.TypeKind.Interface, methods: [] } }, { name: "new", type: { kind: $.TypeKind.Interface, methods: [] } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }],
|
|
98
98
|
Value,
|
|
99
|
-
{"v": { kind: $.TypeKind.Interface, methods: [] }}
|
|
99
|
+
[{ name: "v", key: "v", type: { kind: $.TypeKind.Interface, methods: [] } }]
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -143,7 +143,7 @@ class efaceWords {
|
|
|
143
143
|
new efaceWords(),
|
|
144
144
|
[],
|
|
145
145
|
efaceWords,
|
|
146
|
-
{"data": { kind: $.TypeKind.Basic, name: "Pointer" }, "typ": { kind: $.TypeKind.Basic, name: "Pointer" }}
|
|
146
|
+
[{ name: "data", key: "data", type: { kind: $.TypeKind.Basic, name: "Pointer" } }, { name: "typ", key: "typ", type: { kind: $.TypeKind.Basic, name: "Pointer" } }]
|
|
147
147
|
);
|
|
148
148
|
}
|
|
149
149
|
|
package/gs/sync/meta.json
CHANGED
package/gs/sync/sync.test.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
4
|
+
|
|
5
|
+
import { Cond, Map, Mutex, Pool, RWMutex, WaitGroup } from './sync.js'
|
|
4
6
|
|
|
5
7
|
describe('sync.WaitGroup', () => {
|
|
6
8
|
it('Go tracks scheduled work and unblocks Wait after completion', async () => {
|
|
@@ -89,4 +91,42 @@ describe('sync.Map', () => {
|
|
|
89
91
|
|
|
90
92
|
expect(visited).toEqual(['a:1'])
|
|
91
93
|
})
|
|
94
|
+
|
|
95
|
+
it('matches boxed comparable interface keys', async () => {
|
|
96
|
+
const m = new Map()
|
|
97
|
+
const first = $.namedValueInterfaceValue(8, 'uint16', {}, {
|
|
98
|
+
kind: $.TypeKind.Basic,
|
|
99
|
+
name: 'uint16',
|
|
100
|
+
})
|
|
101
|
+
const second = $.namedValueInterfaceValue(8, 'uint16', {}, {
|
|
102
|
+
kind: $.TypeKind.Basic,
|
|
103
|
+
name: 'uint16',
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
await m.Store(first, 'compressor')
|
|
107
|
+
expect(await m.Load(second)).toEqual(['compressor', true])
|
|
108
|
+
expect(await m.LoadOrStore(second, 'duplicate')).toEqual([
|
|
109
|
+
'compressor',
|
|
110
|
+
true,
|
|
111
|
+
])
|
|
112
|
+
expect(await m.CompareAndSwap(second, 'compressor', 'updated')).toBe(true)
|
|
113
|
+
expect(await m.Load(first)).toEqual(['updated', true])
|
|
114
|
+
expect(await m.CompareAndDelete(first, 'updated')).toBe(true)
|
|
115
|
+
expect(await m.Load(second)).toEqual([undefined, false])
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
describe('sync.Pool', () => {
|
|
120
|
+
it('awaits async New functions before returning a pooled value', async () => {
|
|
121
|
+
const pool = new Pool({
|
|
122
|
+
New: async () => {
|
|
123
|
+
await Promise.resolve()
|
|
124
|
+
return 'created'
|
|
125
|
+
},
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
expect(await pool.Get()).toBe('created')
|
|
129
|
+
pool.Put('reused')
|
|
130
|
+
expect(await pool.Get()).toBe('reused')
|
|
131
|
+
})
|
|
92
132
|
})
|
package/gs/sync/sync.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// low-level library routines. Higher-level synchronization is better done via
|
|
4
4
|
// channels and communication.
|
|
5
5
|
|
|
6
|
+
import { comparableEqual } from '@goscript/builtin/index.js'
|
|
7
|
+
|
|
6
8
|
// Locker represents an object that can be locked and unlocked
|
|
7
9
|
export interface Locker {
|
|
8
10
|
Lock(): Promise<void>
|
|
@@ -334,7 +336,10 @@ export class Map {
|
|
|
334
336
|
public async Delete(key: any): Promise<void> {
|
|
335
337
|
await this._m.Lock()
|
|
336
338
|
try {
|
|
337
|
-
this.
|
|
339
|
+
const entry = this.findEntry(key)
|
|
340
|
+
if (entry.found) {
|
|
341
|
+
this._data.delete(entry.key)
|
|
342
|
+
}
|
|
338
343
|
} finally {
|
|
339
344
|
this._m.Unlock()
|
|
340
345
|
}
|
|
@@ -344,10 +349,11 @@ export class Map {
|
|
|
344
349
|
public async CompareAndDelete(key: any, old: any): Promise<boolean> {
|
|
345
350
|
await this._m.Lock()
|
|
346
351
|
try {
|
|
347
|
-
|
|
352
|
+
const entry = this.findEntry(key)
|
|
353
|
+
if (!entry.found || !comparableEqual(entry.value, old)) {
|
|
348
354
|
return false
|
|
349
355
|
}
|
|
350
|
-
this._data.delete(key)
|
|
356
|
+
this._data.delete(entry.key)
|
|
351
357
|
return true
|
|
352
358
|
} finally {
|
|
353
359
|
this._m.Unlock()
|
|
@@ -356,10 +362,11 @@ export class Map {
|
|
|
356
362
|
|
|
357
363
|
// CompareAndSwap swaps the old and new values for key if the stored value is old.
|
|
358
364
|
public CompareAndSwap(key: any, old: any, value: any): boolean {
|
|
359
|
-
|
|
365
|
+
const entry = this.findEntry(key)
|
|
366
|
+
if (!entry.found || !comparableEqual(entry.value, old)) {
|
|
360
367
|
return false
|
|
361
368
|
}
|
|
362
|
-
this._data.set(key, value)
|
|
369
|
+
this._data.set(entry.key, value)
|
|
363
370
|
return true
|
|
364
371
|
}
|
|
365
372
|
|
|
@@ -367,8 +374,8 @@ export class Map {
|
|
|
367
374
|
public async Load(key: any): Promise<[any, boolean]> {
|
|
368
375
|
await this._m.RLock()
|
|
369
376
|
try {
|
|
370
|
-
const
|
|
371
|
-
return [value,
|
|
377
|
+
const entry = this.findEntry(key)
|
|
378
|
+
return entry.found ? [entry.value, true] : [undefined, false]
|
|
372
379
|
} finally {
|
|
373
380
|
this._m.RUnlock()
|
|
374
381
|
}
|
|
@@ -378,10 +385,12 @@ export class Map {
|
|
|
378
385
|
public async LoadAndDelete(key: any): Promise<[any, boolean]> {
|
|
379
386
|
await this._m.Lock()
|
|
380
387
|
try {
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
388
|
+
const entry = this.findEntry(key)
|
|
389
|
+
if (!entry.found) {
|
|
390
|
+
return [undefined, false]
|
|
391
|
+
}
|
|
392
|
+
this._data.delete(entry.key)
|
|
393
|
+
return [entry.value, true]
|
|
385
394
|
} finally {
|
|
386
395
|
this._m.Unlock()
|
|
387
396
|
}
|
|
@@ -391,8 +400,9 @@ export class Map {
|
|
|
391
400
|
public async LoadOrStore(key: any, value: any): Promise<[any, boolean]> {
|
|
392
401
|
await this._m.Lock()
|
|
393
402
|
try {
|
|
394
|
-
|
|
395
|
-
|
|
403
|
+
const entry = this.findEntry(key)
|
|
404
|
+
if (entry.found) {
|
|
405
|
+
return [entry.value, true]
|
|
396
406
|
}
|
|
397
407
|
this._data.set(key, value)
|
|
398
408
|
return [value, false]
|
|
@@ -423,12 +433,27 @@ export class Map {
|
|
|
423
433
|
public async Store(key: any, value: any): Promise<void> {
|
|
424
434
|
await this._m.Lock()
|
|
425
435
|
try {
|
|
426
|
-
this.
|
|
436
|
+
const entry = this.findEntry(key)
|
|
437
|
+
this._data.set(entry.found ? entry.key : key, value)
|
|
427
438
|
} finally {
|
|
428
439
|
this._m.Unlock()
|
|
429
440
|
}
|
|
430
441
|
}
|
|
431
442
|
|
|
443
|
+
private findEntry(
|
|
444
|
+
key: any,
|
|
445
|
+
): { found: false } | { found: true; key: any; value: any } {
|
|
446
|
+
if (this._data.has(key)) {
|
|
447
|
+
return { found: true, key, value: this._data.get(key) }
|
|
448
|
+
}
|
|
449
|
+
for (const [candidate, value] of this._data.entries()) {
|
|
450
|
+
if (candidate !== key && comparableEqual(candidate, key)) {
|
|
451
|
+
return { found: true, key: candidate, value }
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return { found: false }
|
|
455
|
+
}
|
|
456
|
+
|
|
432
457
|
// Swap swaps the value for a key and returns the previous value if any
|
|
433
458
|
public async Swap(key: any, value: any): Promise<[any, boolean]> {
|
|
434
459
|
await this._m.Lock()
|
|
@@ -458,12 +483,12 @@ export class Pool {
|
|
|
458
483
|
}
|
|
459
484
|
|
|
460
485
|
// Get selects an arbitrary item from the Pool, removes it from the Pool, and returns it to the caller
|
|
461
|
-
public Get(): any {
|
|
486
|
+
public async Get(): Promise<any> {
|
|
462
487
|
if (this._pool.length > 0) {
|
|
463
488
|
return this._pool.pop()
|
|
464
489
|
}
|
|
465
490
|
if (this.New) {
|
|
466
|
-
return this.New()
|
|
491
|
+
return await this.New()
|
|
467
492
|
}
|
|
468
493
|
return null
|
|
469
494
|
}
|
package/gs/syscall/env.ts
CHANGED
|
@@ -1,47 +1,62 @@
|
|
|
1
1
|
import * as $ from '@goscript/builtin/index.js'
|
|
2
2
|
|
|
3
|
+
type ProcessEnv = Record<string, string | undefined>
|
|
4
|
+
|
|
5
|
+
interface ProcessLike {
|
|
6
|
+
env?: ProcessEnv
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function hostEnv(): ProcessEnv | undefined {
|
|
10
|
+
return (globalThis as { process?: ProcessLike }).process?.env
|
|
11
|
+
}
|
|
12
|
+
|
|
3
13
|
// Environment variable functions using Node.js/browser APIs
|
|
4
14
|
export function Getenv(key: string): [string, boolean] {
|
|
5
|
-
|
|
6
|
-
|
|
15
|
+
const env = hostEnv()
|
|
16
|
+
if (env !== undefined) {
|
|
17
|
+
const value = env[key]
|
|
7
18
|
return value !== undefined ? [value, true] : ['', false]
|
|
8
19
|
}
|
|
9
20
|
return ['', false]
|
|
10
21
|
}
|
|
11
22
|
|
|
12
23
|
export function Setenv(key: string, value: string): $.GoError {
|
|
13
|
-
|
|
14
|
-
|
|
24
|
+
const env = hostEnv()
|
|
25
|
+
if (env !== undefined) {
|
|
26
|
+
env[key] = value
|
|
15
27
|
return null
|
|
16
28
|
}
|
|
17
29
|
return { Error: () => 'setenv not supported' }
|
|
18
30
|
}
|
|
19
31
|
|
|
20
32
|
export function Unsetenv(key: string): $.GoError {
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
const env = hostEnv()
|
|
34
|
+
if (env !== undefined) {
|
|
35
|
+
delete env[key]
|
|
23
36
|
return null
|
|
24
37
|
}
|
|
25
38
|
return { Error: () => 'unsetenv not supported' }
|
|
26
39
|
}
|
|
27
40
|
|
|
28
41
|
export function Clearenv(): void {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
const env = hostEnv()
|
|
43
|
+
if (env !== undefined) {
|
|
44
|
+
for (const key in env) {
|
|
45
|
+
delete env[key]
|
|
32
46
|
}
|
|
33
47
|
}
|
|
34
48
|
}
|
|
35
49
|
|
|
36
50
|
export function Environ(): $.Slice<string> {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
const host = hostEnv()
|
|
52
|
+
if (host !== undefined) {
|
|
53
|
+
const values: string[] = []
|
|
54
|
+
for (const [key, value] of Object.entries(host)) {
|
|
40
55
|
if (value !== undefined) {
|
|
41
|
-
|
|
56
|
+
values.push(`${key}=${value}`)
|
|
42
57
|
}
|
|
43
58
|
}
|
|
44
|
-
return $.arrayToSlice(
|
|
59
|
+
return $.arrayToSlice(values)
|
|
45
60
|
}
|
|
46
61
|
return $.arrayToSlice([])
|
|
47
62
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
4
|
+
|
|
5
|
+
import { ValueOf } from './index.js'
|
|
6
|
+
|
|
7
|
+
describe('syscall/js override', () => {
|
|
8
|
+
test('ValueOf unwraps generated interface numeric boxes', () => {
|
|
9
|
+
const value = ValueOf(
|
|
10
|
+
$.namedValueInterfaceValue(41, 'int', {}, {
|
|
11
|
+
kind: $.TypeKind.Basic,
|
|
12
|
+
name: 'int',
|
|
13
|
+
}),
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
expect(value.Int()).toBe(41)
|
|
17
|
+
})
|
|
18
|
+
})
|
package/gs/syscall/js/index.ts
CHANGED
|
@@ -365,6 +365,9 @@ export function ValueOf(x: unknown): Value {
|
|
|
365
365
|
if (x instanceof Func) {
|
|
366
366
|
return x.Value.clone()
|
|
367
367
|
}
|
|
368
|
+
if (isGoInterfaceValue(x)) {
|
|
369
|
+
return ValueOf(x.__goValue)
|
|
370
|
+
}
|
|
368
371
|
if (x === null || x === undefined) {
|
|
369
372
|
return Null()
|
|
370
373
|
}
|
|
@@ -394,6 +397,15 @@ export function ValueOf(x: unknown): Value {
|
|
|
394
397
|
return new Value({ raw: x })
|
|
395
398
|
}
|
|
396
399
|
|
|
400
|
+
function isGoInterfaceValue(value: unknown): value is { __goValue: unknown } {
|
|
401
|
+
return (
|
|
402
|
+
value !== null &&
|
|
403
|
+
typeof value === 'object' &&
|
|
404
|
+
'__goValue' in value &&
|
|
405
|
+
typeof (value as { __goType?: unknown }).__goType === 'string'
|
|
406
|
+
)
|
|
407
|
+
}
|
|
408
|
+
|
|
397
409
|
export function FuncOf(
|
|
398
410
|
fn: (this$: Value, args: $.Slice<Value>) => unknown,
|
|
399
411
|
): Func {
|