goscript 0.1.4 → 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} +7 -0
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- 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 +273 -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 +392 -127
- package/compiler/lowering_bench_test.go +41 -27
- 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/protobuf-ts-binding.go +514 -0
- package/compiler/protobuf-ts-binding_test.go +172 -0
- package/compiler/semantic-model-types.go +9 -4
- package/compiler/semantic-model.go +282 -70
- package/compiler/semantic-model_test.go +82 -1
- package/compiler/service.go +20 -1
- package/compiler/skeleton_test.go +62 -8
- package/compiler/typescript-emitter.go +128 -13
- package/dist/gs/builtin/slice.d.ts +2 -1
- package/dist/gs/builtin/slice.js +29 -4
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +13 -5
- package/dist/gs/builtin/type.js +153 -60
- 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 +10 -3
- package/dist/gs/compress/zlib/index.js +50 -16
- package/dist/gs/compress/zlib/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/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/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 +4 -2
- 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 +2 -0
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +5 -0
- package/dist/gs/math/bits/index.js +16 -4
- 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 +300 -5
- package/dist/gs/net/http/index.js +1598 -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.js +1 -1
- 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 +25 -6
- package/dist/gs/reflect/type.js +1418 -228
- 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.js +9 -5
- 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/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/testing/testing.js +55 -13
- 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/runtime-contract.test.ts +218 -21
- package/gs/builtin/slice.ts +44 -4
- package/gs/builtin/type.ts +226 -59
- 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 +62 -1
- package/gs/compress/zlib/index.ts +53 -16
- package/gs/compress/zlib/parity.json +51 -0
- 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/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/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.ts +4 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.ts +1 -0
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +23 -4
- 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 +781 -12
- package/gs/net/http/index.ts +1860 -139
- 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/index.test.ts +9 -0
- package/gs/os/index.ts +1 -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/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +1 -1
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- 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 +1897 -317
- package/gs/reflect/typefor.test.ts +510 -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/parity.json +186 -0
- package/gs/strings/reader.ts +9 -5
- 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/syscall/env.ts +29 -14
- package/gs/testing/testing.test.ts +67 -0
- package/gs/testing/testing.ts +87 -19
- 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 -926
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -38
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1361
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
- /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
|
@@ -242,6 +242,87 @@ func TestSemanticModelRecordsInterfaceAssertionAndNilFacts(t *testing.T) {
|
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
func TestSemanticModelRejectsInterfaceMethodSignatureMismatch(t *testing.T) {
|
|
246
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
247
|
+
"go.mod": "module example.test/signaturemismatch\n\ngo 1.25.3\n",
|
|
248
|
+
"main.go": strings.Join([]string{
|
|
249
|
+
"package signaturemismatch",
|
|
250
|
+
"type Reader interface { Read() int }",
|
|
251
|
+
"type Impl struct{}",
|
|
252
|
+
"func (Impl) Read() string { return \"bad\" }",
|
|
253
|
+
"",
|
|
254
|
+
}, "\n"),
|
|
255
|
+
})
|
|
256
|
+
graph := loadPackageGraph(t, &CompileRequest{
|
|
257
|
+
Patterns: []string{"."},
|
|
258
|
+
Dir: moduleDir,
|
|
259
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
260
|
+
DependencyMode: DependencyModeRequested,
|
|
261
|
+
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
262
|
+
})
|
|
263
|
+
model := buildSemanticModel(t, graph)
|
|
264
|
+
|
|
265
|
+
if hasInterfaceImplementation(model, "Impl", "Reader", false) {
|
|
266
|
+
t.Fatalf("unexpected Impl -> Reader implementation: %#v", model.interfaceImplementations)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
func TestSemanticModelAcceptsPromotedInterfaceMethods(t *testing.T) {
|
|
271
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
272
|
+
"go.mod": "module example.test/promoted\n\ngo 1.25.3\n",
|
|
273
|
+
"main.go": strings.Join([]string{
|
|
274
|
+
"package promoted",
|
|
275
|
+
"type Reader interface { Read() int }",
|
|
276
|
+
"type Base struct{}",
|
|
277
|
+
"func (Base) Read() int { return 1 }",
|
|
278
|
+
"type Impl struct { Base }",
|
|
279
|
+
"",
|
|
280
|
+
}, "\n"),
|
|
281
|
+
})
|
|
282
|
+
graph := loadPackageGraph(t, &CompileRequest{
|
|
283
|
+
Patterns: []string{"."},
|
|
284
|
+
Dir: moduleDir,
|
|
285
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
286
|
+
DependencyMode: DependencyModeRequested,
|
|
287
|
+
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
288
|
+
})
|
|
289
|
+
model := buildSemanticModel(t, graph)
|
|
290
|
+
|
|
291
|
+
if !hasInterfaceImplementation(model, "Impl", "Reader", false) {
|
|
292
|
+
t.Fatalf("missing promoted Impl -> Reader implementation: %#v", model.interfaceImplementations)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
func TestSemanticModelKeepsUnexportedInterfaceMethodsPackageScoped(t *testing.T) {
|
|
297
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
298
|
+
"go.mod": "module example.test/unexportediface\n\ngo 1.25.3\n",
|
|
299
|
+
"dep/dep.go": strings.Join([]string{
|
|
300
|
+
"package dep",
|
|
301
|
+
"type private interface { read() int }",
|
|
302
|
+
"",
|
|
303
|
+
}, "\n"),
|
|
304
|
+
"main.go": strings.Join([]string{
|
|
305
|
+
"package unexportediface",
|
|
306
|
+
"import _ \"example.test/unexportediface/dep\"",
|
|
307
|
+
"type Impl struct{}",
|
|
308
|
+
"func (Impl) read() int { return 1 }",
|
|
309
|
+
"",
|
|
310
|
+
}, "\n"),
|
|
311
|
+
})
|
|
312
|
+
graph := loadPackageGraph(t, &CompileRequest{
|
|
313
|
+
Patterns: []string{"."},
|
|
314
|
+
Dir: moduleDir,
|
|
315
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
316
|
+
DependencyMode: DependencyModeAll,
|
|
317
|
+
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
318
|
+
})
|
|
319
|
+
model := buildSemanticModel(t, graph)
|
|
320
|
+
|
|
321
|
+
if hasInterfaceImplementation(model, "Impl", "private", false) {
|
|
322
|
+
t.Fatalf("unexpected cross-package unexported implementation: %#v", model.interfaceImplementations)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
245
326
|
func TestSemanticModelColorsAsyncFunctionsAndOverrides(t *testing.T) {
|
|
246
327
|
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
247
328
|
"go.mod": "module example.test/async\n\ngo 1.25.3\n",
|
|
@@ -356,7 +437,7 @@ func TestSemanticModelPropagatesAsyncToOverrideInterfaceMethods(t *testing.T) {
|
|
|
356
437
|
if implementation.typ != nil && implementation.typ.Obj().Name() == "asyncWriter" &&
|
|
357
438
|
implementation.iface != nil && implementation.iface.Obj().Pkg().Path() == "io" &&
|
|
358
439
|
implementation.iface.Obj().Name() == "Writer" &&
|
|
359
|
-
implementation.pointer
|
|
440
|
+
implementation.pointer {
|
|
360
441
|
found = true
|
|
361
442
|
break
|
|
362
443
|
}
|
package/compiler/service.go
CHANGED
|
@@ -14,6 +14,7 @@ type CompileService struct {
|
|
|
14
14
|
emitterOwner *TypeScriptEmitOwner
|
|
15
15
|
runtimeOwner *RuntimeContractOwner
|
|
16
16
|
overrideOwner *OverrideRegistryOwner
|
|
17
|
+
parityOwner *OverrideParityVerifier
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
// NewCompileService creates a compile service with every pipeline owner.
|
|
@@ -28,6 +29,7 @@ func NewCompileService(overrideDirs ...string) *CompileService {
|
|
|
28
29
|
emitterOwner: NewTypeScriptEmitOwner(runtimeOwner),
|
|
29
30
|
runtimeOwner: runtimeOwner,
|
|
30
31
|
overrideOwner: overrideOwner,
|
|
32
|
+
parityOwner: NewOverrideParityVerifier(),
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
|
|
@@ -96,6 +98,19 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
|
|
|
96
98
|
return result, NewCompileError(diagnostics)
|
|
97
99
|
}
|
|
98
100
|
|
|
101
|
+
overrideFacts, factsDiagnostics := s.overrideOwner.Facts(ctx)
|
|
102
|
+
diagnostics = append(diagnostics, factsDiagnostics...)
|
|
103
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
104
|
+
result.Diagnostics = diagnostics
|
|
105
|
+
return result, NewCompileError(diagnostics)
|
|
106
|
+
}
|
|
107
|
+
parityDiagnostics := s.parityOwner.Verify(ctx, graph, overrideFacts)
|
|
108
|
+
diagnostics = append(diagnostics, parityDiagnostics...)
|
|
109
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
110
|
+
result.Diagnostics = diagnostics
|
|
111
|
+
return result, NewCompileError(diagnostics)
|
|
112
|
+
}
|
|
113
|
+
|
|
99
114
|
semanticModel, semanticDiagnostics := s.semanticOwner.Build(ctx, graph)
|
|
100
115
|
diagnostics = append(diagnostics, semanticDiagnostics...)
|
|
101
116
|
if diagnosticsHaveErrors(diagnostics) {
|
|
@@ -110,7 +125,11 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
|
|
|
110
125
|
return result, NewCompileError(diagnostics)
|
|
111
126
|
}
|
|
112
127
|
|
|
113
|
-
loweredProgram, loweringDiagnostics := s.loweringOwner.Build(ctx, semanticModel
|
|
128
|
+
loweredProgram, loweringDiagnostics := s.loweringOwner.Build(ctx, semanticModel, LoweringOptions{
|
|
129
|
+
SourceRoot: protobufTypeScriptBindingRoot(req.Dir),
|
|
130
|
+
OutputPath: req.OutputPath,
|
|
131
|
+
ProtobufTypeScriptBinding: req.ProtobufTypeScriptBinding,
|
|
132
|
+
})
|
|
114
133
|
diagnostics = append(diagnostics, loweringDiagnostics...)
|
|
115
134
|
if diagnosticsHaveErrors(diagnostics) {
|
|
116
135
|
result.Diagnostics = diagnostics
|
|
@@ -911,6 +911,49 @@ func TestCompilePackagesAnnotatesNewPointerShortDecls(t *testing.T) {
|
|
|
911
911
|
}
|
|
912
912
|
}
|
|
913
913
|
|
|
914
|
+
func TestCompilePackagesAnnotatesNewArrayPointerShortDecls(t *testing.T) {
|
|
915
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
916
|
+
"go.mod": "module example.test/newarrayptrdecl\n\ngo 1.25.3\n",
|
|
917
|
+
"main.go": strings.Join([]string{
|
|
918
|
+
"package main",
|
|
919
|
+
"func use(*[32]byte) {}",
|
|
920
|
+
"func main() {",
|
|
921
|
+
" buf := new([32]byte)",
|
|
922
|
+
" use(buf)",
|
|
923
|
+
" if true {",
|
|
924
|
+
" buf = nil",
|
|
925
|
+
" }",
|
|
926
|
+
" use(buf)",
|
|
927
|
+
"}",
|
|
928
|
+
"",
|
|
929
|
+
}, "\n"),
|
|
930
|
+
})
|
|
931
|
+
outputDir := filepath.Join(t.TempDir(), "output")
|
|
932
|
+
comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir}, nil, nil)
|
|
933
|
+
if err != nil {
|
|
934
|
+
t.Fatal(err.Error())
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
|
|
938
|
+
t.Fatal(err.Error())
|
|
939
|
+
}
|
|
940
|
+
outputFile := filepath.Join(outputDir, "@goscript", "example.test", "newarrayptrdecl", "main.gs.ts")
|
|
941
|
+
content, err := os.ReadFile(outputFile)
|
|
942
|
+
if err != nil {
|
|
943
|
+
t.Fatal(err.Error())
|
|
944
|
+
}
|
|
945
|
+
text := string(content)
|
|
946
|
+
for _, want := range []string{
|
|
947
|
+
"let buf: $.VarRef<Uint8Array> | null = $.varRef<Uint8Array>(new Uint8Array(32))",
|
|
948
|
+
"buf = null",
|
|
949
|
+
"use(buf)",
|
|
950
|
+
} {
|
|
951
|
+
if !strings.Contains(text, want) {
|
|
952
|
+
t.Fatalf("missing %q in generated output:\n%s", want, text)
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
914
957
|
func TestCompilePackagesEmitsShadowedBuiltinCalls(t *testing.T) {
|
|
915
958
|
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
916
959
|
"go.mod": "module example.test/shadowbuiltin\n\ngo 1.25.3\n",
|
|
@@ -1516,8 +1559,8 @@ func TestCompilePackagesEmitsStructMethodsAndPointerAssertions(t *testing.T) {
|
|
|
1516
1559
|
"Counter.prototype.Set.call(pointer, 2)",
|
|
1517
1560
|
"Counter.prototype.Set.call(NewCounter(), 5)",
|
|
1518
1561
|
"let [, ok] = $.typeAssertTuple<Counter | $.VarRef<Counter> | null>(iface, { kind: $.TypeKind.Pointer, elemType: \"main.Counter\" })",
|
|
1519
|
-
"\"Value\":
|
|
1520
|
-
"\"ID\": { kind: $.TypeKind.Basic, name: \"int32\", typeName: \"main.ObjectID\" }",
|
|
1562
|
+
"{ name: \"Value\", key: \"Value\", type: { kind: $.TypeKind.Basic, name: \"int\" }, tag: \"json:\\\"value\\\"\", index: [0], offset: 0, exported: true }",
|
|
1563
|
+
"{ name: \"ID\", key: \"ID\", type: { kind: $.TypeKind.Basic, name: \"int32\", typeName: \"main.ObjectID\" }, index: [1], offset: 8, exported: true }",
|
|
1521
1564
|
} {
|
|
1522
1565
|
if !strings.Contains(text, want) {
|
|
1523
1566
|
t.Fatalf("missing %q in generated output:\n%s", want, text)
|
|
@@ -2346,9 +2389,11 @@ func TestCompilePackagesEmitsInterfacesMethodValuesTypeSwitchesAndFunctionAssert
|
|
|
2346
2389
|
"Close(): string",
|
|
2347
2390
|
"$.registerInterfaceType(\n\t\"main.ReadCloser\"",
|
|
2348
2391
|
"((__receiver) => () => __receiver.Inc())($.pointerValue<Counter>(counter))",
|
|
2349
|
-
"$.namedFunction(greet, \"main.Greeter\"
|
|
2392
|
+
"$.namedFunction(greet, \"main.Greeter\", ({ kind: $.TypeKind.Function, name: \"main.Greeter\"",
|
|
2393
|
+
"params: [{ kind: $.TypeKind.Basic, name: \"string\" }]",
|
|
2394
|
+
"results: [{ kind: $.TypeKind.Basic, name: \"string\" }]",
|
|
2350
2395
|
"$.interfaceValue<any>(null, \"*struct{Name string}\")",
|
|
2351
|
-
"elemType: { kind: $.TypeKind.Struct, methods: [], fields: {\"Name\": { kind: $.TypeKind.Basic, name: \"string\" }
|
|
2396
|
+
"elemType: { kind: $.TypeKind.Struct, methods: [], fields: [{ name: \"Name\", key: \"Name\", type: { kind: $.TypeKind.Basic, name: \"string\" }",
|
|
2352
2397
|
"let fn = __goscriptTuple",
|
|
2353
2398
|
"switch (true)",
|
|
2354
2399
|
"case $.typeAssert<Exclude<ReadCloser, null>>(__goscriptTypeSwitchValue, \"main.ReadCloser\").ok",
|
|
@@ -2612,9 +2657,9 @@ func TestCompilePackagesEmitsGenericMethodsAliasesAndDictionaries(t *testing.T)
|
|
|
2612
2657
|
"$.mapSet(seen, 1, {})",
|
|
2613
2658
|
"$.genericZero(__typeArgs, \"T\", null)",
|
|
2614
2659
|
"$.callGenericMethod(__typeArgs, \"T\", \"String\", v)",
|
|
2615
|
-
"ZeroValue({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)} }})",
|
|
2616
|
-
"CallString({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)} }}, zero)",
|
|
2617
|
-
"Sum({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)} }}, null)",
|
|
2660
|
+
"ZeroValue({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)}, methodSignatures: [{ name: \"String\", args: [], returns: [{ name: \"_r0\", type: { kind: $.TypeKind.Basic, name: \"string\" } }] }] }})",
|
|
2661
|
+
"CallString({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)}, methodSignatures: [{ name: \"String\", args: [], returns: [{ name: \"_r0\", type: { kind: $.TypeKind.Basic, name: \"string\" } }] }] }}, zero)",
|
|
2662
|
+
"Sum({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)}, methodSignatures: [{ name: \"String\", args: [], returns: [{ name: \"_r0\", type: { kind: $.TypeKind.Basic, name: \"string\" } }] }] }}, null)",
|
|
2618
2663
|
} {
|
|
2619
2664
|
if !strings.Contains(text, want) {
|
|
2620
2665
|
t.Fatalf("missing %q in generated output:\n%s", want, text)
|
|
@@ -2761,7 +2806,7 @@ func TestCompilePackagesEmitsRecursiveFunctionTypeInfo(t *testing.T) {
|
|
|
2761
2806
|
text := string(content)
|
|
2762
2807
|
for _, want := range []string{
|
|
2763
2808
|
"export type Handler = ((_p0: ((_p0: Handler | null) => Handler | null | globalThis.Promise<Handler | null>) | null) => Handler | null | globalThis.Promise<Handler | null>) | null",
|
|
2764
|
-
"\"Next\": ({ kind: $.TypeKind.Function, name: \"main.Handler\"",
|
|
2809
|
+
"{ name: \"Next\", key: \"Next\", type: ({ kind: $.TypeKind.Function, name: \"main.Handler\"",
|
|
2765
2810
|
"params: [{ kind: $.TypeKind.Function, params: [], results: [] }]",
|
|
2766
2811
|
"results: [{ kind: $.TypeKind.Function, params: [], results: [] }]",
|
|
2767
2812
|
} {
|
|
@@ -4127,6 +4172,12 @@ func TestCompilePackagesLowersSwitchesAndFunctionValueCalls(t *testing.T) {
|
|
|
4127
4172
|
" if value > 0 {",
|
|
4128
4173
|
" goto Again",
|
|
4129
4174
|
" }",
|
|
4175
|
+
"Drive:",
|
|
4176
|
+
" window := value + 1",
|
|
4177
|
+
" if window < 0 {",
|
|
4178
|
+
" goto Drive",
|
|
4179
|
+
" }",
|
|
4180
|
+
" println(window)",
|
|
4130
4181
|
" release := func() { println(\"release\") }",
|
|
4131
4182
|
" rel := &release",
|
|
4132
4183
|
" (*rel)()",
|
|
@@ -4163,6 +4214,9 @@ func TestCompilePackagesLowersSwitchesAndFunctionValueCalls(t *testing.T) {
|
|
|
4163
4214
|
"break Block",
|
|
4164
4215
|
"Again: while (true)",
|
|
4165
4216
|
"continue Again",
|
|
4217
|
+
"Drive: while (true)",
|
|
4218
|
+
"var window = value + 1",
|
|
4219
|
+
"$.println(window)",
|
|
4166
4220
|
"($.pointerValue<(() => void) | null>(rel))!()",
|
|
4167
4221
|
"$.functionValue((): void => {\n\t\tusing __defer = new $.DisposableStack()",
|
|
4168
4222
|
"__defer.defer(() => { $.println(\"wrapped deferred\") })",
|
|
@@ -134,6 +134,7 @@ func (o *TypeScriptEmitOwner) EmitToMemory(
|
|
|
134
134
|
|
|
135
135
|
func (o *TypeScriptEmitOwner) renderLoweredFile(pkg *loweredPackage, file *loweredFile) string {
|
|
136
136
|
var b strings.Builder
|
|
137
|
+
b.Grow(estimateLoweredFileSize(file))
|
|
137
138
|
if file.sourcePath != "" {
|
|
138
139
|
b.WriteString("// Generated file based on ")
|
|
139
140
|
b.WriteString(filepath.Base(file.sourcePath))
|
|
@@ -219,6 +220,104 @@ func (o *TypeScriptEmitOwner) renderLoweredFile(pkg *loweredPackage, file *lower
|
|
|
219
220
|
return b.String()
|
|
220
221
|
}
|
|
221
222
|
|
|
223
|
+
func estimateLoweredFileSize(file *loweredFile) int {
|
|
224
|
+
if file == nil {
|
|
225
|
+
return 0
|
|
226
|
+
}
|
|
227
|
+
size := 128 + len(file.imports)*96 + len(file.decls)*32
|
|
228
|
+
for _, imp := range file.imports {
|
|
229
|
+
size += len(imp.alias) + len(imp.source)
|
|
230
|
+
}
|
|
231
|
+
for _, decl := range file.decls {
|
|
232
|
+
size += len(decl.code)
|
|
233
|
+
if decl.function != nil {
|
|
234
|
+
size += estimateLoweredFunctionSize(decl.function)
|
|
235
|
+
}
|
|
236
|
+
if decl.structType != nil {
|
|
237
|
+
size += estimateLoweredStructSize(decl.structType)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return size
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
func estimateLoweredStructSize(structType *loweredStruct) int {
|
|
244
|
+
if structType == nil {
|
|
245
|
+
return 0
|
|
246
|
+
}
|
|
247
|
+
size := 256 + len(structType.name) + len(structType.typeName) + len(structType.fields)*128
|
|
248
|
+
for _, field := range structType.fields {
|
|
249
|
+
size += len(field.name) + len(field.runtimeName) + len(field.typ) + len(field.zero) + len(field.runtimeType) +
|
|
250
|
+
len(field.doc) + len(field.tag)
|
|
251
|
+
}
|
|
252
|
+
for idx := range structType.methods {
|
|
253
|
+
size += estimateLoweredFunctionSize(&structType.methods[idx])
|
|
254
|
+
}
|
|
255
|
+
return size
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
func estimateLoweredFunctionSize(fn *loweredFunction) int {
|
|
259
|
+
if fn == nil {
|
|
260
|
+
return 0
|
|
261
|
+
}
|
|
262
|
+
size := 192 + len(fn.name) + len(fn.result) + len(fn.receiverAlias) + len(fn.receiverType) + len(fn.receiverValue)
|
|
263
|
+
for _, typeParam := range fn.typeParams {
|
|
264
|
+
size += len(typeParam) + 2
|
|
265
|
+
}
|
|
266
|
+
for _, param := range fn.params {
|
|
267
|
+
size += len(param.name) + len(param.typ) + 4
|
|
268
|
+
}
|
|
269
|
+
for _, result := range fn.namedResults {
|
|
270
|
+
size += len(result.name) + len(result.typ) + len(result.zero) + len(result.returnExpr) + 16
|
|
271
|
+
}
|
|
272
|
+
size += estimateLoweredStmtsSize(fn.paramBindings)
|
|
273
|
+
size += estimateLoweredStmtsSize(fn.body)
|
|
274
|
+
return size
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
func estimateLoweredStmtsSize(stmts []loweredStmt) int {
|
|
278
|
+
size := len(stmts) * 24
|
|
279
|
+
for _, stmt := range stmts {
|
|
280
|
+
size += len(stmt.text) + len(stmt.leading)*16
|
|
281
|
+
for _, line := range stmt.leading {
|
|
282
|
+
size += len(line)
|
|
283
|
+
}
|
|
284
|
+
size += estimateLoweredStmtsSize(stmt.children)
|
|
285
|
+
size += estimateLoweredStmtsSize(stmt.elseBody)
|
|
286
|
+
if stmt.rangeFunc != nil {
|
|
287
|
+
size += len(stmt.rangeFunc.value) + len(stmt.rangeFunc.params)*16 + estimateLoweredStmtsSize(stmt.rangeFunc.body)
|
|
288
|
+
}
|
|
289
|
+
if stmt.switchStmt != nil {
|
|
290
|
+
size += len(stmt.switchStmt.value)
|
|
291
|
+
for _, switchCase := range stmt.switchStmt.cases {
|
|
292
|
+
size += len(switchCase.values)*16 + estimateLoweredStmtsSize(switchCase.body)
|
|
293
|
+
for _, value := range switchCase.values {
|
|
294
|
+
size += len(value)
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if stmt.selectStmt != nil {
|
|
299
|
+
size += len(stmt.selectStmt.hasReturn) + len(stmt.selectStmt.value) + len(stmt.selectStmt.result) + len(stmt.selectStmt.resultType)
|
|
300
|
+
for _, selectCase := range stmt.selectStmt.cases {
|
|
301
|
+
size += len(selectCase.channel) + len(selectCase.value) + estimateLoweredStmtsSize(selectCase.prelude) +
|
|
302
|
+
estimateLoweredStmtsSize(selectCase.body)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if stmt.typeSwitch != nil {
|
|
306
|
+
size += len(stmt.typeSwitch.value) + len(stmt.typeSwitch.varName) + estimateLoweredStmtsSize(stmt.typeSwitch.defaultBody)
|
|
307
|
+
for _, switchCase := range stmt.typeSwitch.cases {
|
|
308
|
+
for _, typ := range switchCase.types {
|
|
309
|
+
size += len(typ)
|
|
310
|
+
}
|
|
311
|
+
for _, typ := range switchCase.tsTypes {
|
|
312
|
+
size += len(typ)
|
|
313
|
+
}
|
|
314
|
+
size += estimateLoweredStmtsSize(switchCase.body)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return size
|
|
319
|
+
}
|
|
320
|
+
|
|
222
321
|
func sortedStructDecls(decls []loweredDecl) []loweredDecl {
|
|
223
322
|
structs := make([]loweredDecl, 0)
|
|
224
323
|
names := make(map[string]bool)
|
|
@@ -421,29 +520,42 @@ func renderStruct(b *strings.Builder, structType *loweredStruct, runtimeOwner *R
|
|
|
421
520
|
if idx != 0 {
|
|
422
521
|
b.WriteString(", ")
|
|
423
522
|
}
|
|
424
|
-
|
|
425
|
-
if method.runtimeName != "" {
|
|
426
|
-
methodName = method.runtimeName
|
|
427
|
-
}
|
|
428
|
-
b.WriteString("{ name: ")
|
|
429
|
-
b.WriteString(strconvQuote(methodName))
|
|
430
|
-
b.WriteString(", args: [], returns: [] }")
|
|
523
|
+
b.WriteString(runtimeMethodSignatureExpr(method))
|
|
431
524
|
}
|
|
432
525
|
b.WriteString("],\n\t\t")
|
|
433
526
|
b.WriteString(structType.name)
|
|
434
|
-
b.WriteString(",\n\t\t
|
|
527
|
+
b.WriteString(",\n\t\t[")
|
|
435
528
|
for idx, field := range structType.fields {
|
|
436
529
|
if idx != 0 {
|
|
437
530
|
b.WriteString(", ")
|
|
438
531
|
}
|
|
439
|
-
b.WriteString(
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
532
|
+
b.WriteString(runtimeStructFieldInfoExpr(
|
|
533
|
+
field.runtimeType,
|
|
534
|
+
field.name,
|
|
535
|
+
field.runtimeName,
|
|
536
|
+
field.tag,
|
|
537
|
+
field.pkgPath,
|
|
538
|
+
field.anonymous,
|
|
539
|
+
field.index,
|
|
540
|
+
field.offset,
|
|
541
|
+
field.exported,
|
|
542
|
+
))
|
|
543
|
+
}
|
|
544
|
+
b.WriteString("]\n\t)\n")
|
|
444
545
|
b.WriteString("}\n")
|
|
445
546
|
}
|
|
446
547
|
|
|
548
|
+
func runtimeMethodSignatureExpr(method loweredFunction) string {
|
|
549
|
+
if method.runtimeSignature != "" {
|
|
550
|
+
return method.runtimeSignature
|
|
551
|
+
}
|
|
552
|
+
methodName := method.name
|
|
553
|
+
if method.runtimeName != "" {
|
|
554
|
+
methodName = method.runtimeName
|
|
555
|
+
}
|
|
556
|
+
return "{ name: " + strconvQuote(methodName) + ", args: [], returns: [] }"
|
|
557
|
+
}
|
|
558
|
+
|
|
447
559
|
func writeLineComment(b *strings.Builder, indent string, comment string) {
|
|
448
560
|
comment = strings.TrimSpace(comment)
|
|
449
561
|
if comment == "" {
|
|
@@ -1158,6 +1270,9 @@ func renderIndex(pkg *loweredPackage) string {
|
|
|
1158
1270
|
if file.sideEffect {
|
|
1159
1271
|
lines = append(lines, "import \"./"+file.outputName+"\"")
|
|
1160
1272
|
}
|
|
1273
|
+
if file.exportAll {
|
|
1274
|
+
lines = append(lines, "export * from \"./"+file.outputName+"\"")
|
|
1275
|
+
}
|
|
1161
1276
|
exports := slices.Clone(file.exports)
|
|
1162
1277
|
slices.Sort(exports)
|
|
1163
1278
|
if len(exports) != 0 {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type VarRef } from './varRef.js';
|
|
1
|
+
import { type OwnedPointerHandle, type VarRef } from './varRef.js';
|
|
2
2
|
export declare class GoBinaryString extends String {
|
|
3
3
|
readonly bytes: Uint8Array;
|
|
4
4
|
constructor(bytes: Uint8Array);
|
|
@@ -119,6 +119,7 @@ export declare function index<T>(collection: GoStringValue | Slice<T> | T[], ind
|
|
|
119
119
|
* indexRef returns an addressable reference to a slice or array element.
|
|
120
120
|
*/
|
|
121
121
|
export declare function indexRef<T>(collection: Slice<T> | T[] | Uint8Array, index: number): VarRef<T>;
|
|
122
|
+
export declare function sliceFromOwnedPointer<T>(pointer: OwnedPointerHandle<T>, length: number): Slice<T> | Uint8Array;
|
|
122
123
|
/**
|
|
123
124
|
* arrayPointerFromIndexRef turns &slice[i] into a pointer to an N-element array
|
|
124
125
|
* view. This models unsafe conversions such as (*[64]byte)(unsafe.Pointer(&b[0]))
|
package/dist/gs/builtin/slice.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isVarRef, varRef } from './varRef.js';
|
|
1
|
+
import { isOwnedPointerHandle, isVarRef, varRef, } from './varRef.js';
|
|
2
2
|
export class GoBinaryString extends String {
|
|
3
3
|
bytes;
|
|
4
4
|
constructor(bytes) {
|
|
@@ -926,7 +926,7 @@ export function indexRef(collection, index) {
|
|
|
926
926
|
if (index < 0 || index >= collection.length) {
|
|
927
927
|
throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
|
|
928
928
|
}
|
|
929
|
-
|
|
929
|
+
const ref = {
|
|
930
930
|
get value() {
|
|
931
931
|
return collection[index];
|
|
932
932
|
},
|
|
@@ -938,13 +938,15 @@ export function indexRef(collection, index) {
|
|
|
938
938
|
__goCollection: collection,
|
|
939
939
|
__goIndex: index,
|
|
940
940
|
};
|
|
941
|
+
ref.__goPointer = collectionPointer(ref, collection, index);
|
|
942
|
+
return ref;
|
|
941
943
|
}
|
|
942
944
|
if (isComplexSlice(collection)) {
|
|
943
945
|
if (index < 0 || index >= collection.__meta__.length) {
|
|
944
946
|
throw new Error(`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`);
|
|
945
947
|
}
|
|
946
948
|
const backingIndex = collection.__meta__.offset + index;
|
|
947
|
-
|
|
949
|
+
const ref = {
|
|
948
950
|
get value() {
|
|
949
951
|
return collection.__meta__.backing[backingIndex];
|
|
950
952
|
},
|
|
@@ -956,12 +958,14 @@ export function indexRef(collection, index) {
|
|
|
956
958
|
__goCollection: collection,
|
|
957
959
|
__goIndex: index,
|
|
958
960
|
};
|
|
961
|
+
ref.__goPointer = collectionPointer(ref, collection, index);
|
|
962
|
+
return ref;
|
|
959
963
|
}
|
|
960
964
|
if (Array.isArray(collection)) {
|
|
961
965
|
if (index < 0 || index >= collection.length) {
|
|
962
966
|
throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
|
|
963
967
|
}
|
|
964
|
-
|
|
968
|
+
const ref = {
|
|
965
969
|
get value() {
|
|
966
970
|
return collection[index];
|
|
967
971
|
},
|
|
@@ -973,9 +977,30 @@ export function indexRef(collection, index) {
|
|
|
973
977
|
__goCollection: collection,
|
|
974
978
|
__goIndex: index,
|
|
975
979
|
};
|
|
980
|
+
ref.__goPointer = collectionPointer(ref, collection, index);
|
|
981
|
+
return ref;
|
|
976
982
|
}
|
|
977
983
|
throw new Error('runtime error: index on unsupported type');
|
|
978
984
|
}
|
|
985
|
+
function collectionPointer(ref, collection, index) {
|
|
986
|
+
return {
|
|
987
|
+
__goOwnedPointer: true,
|
|
988
|
+
__goAddress: () => indexAddress(collection, index),
|
|
989
|
+
__goRef: () => ref,
|
|
990
|
+
__goSlice: (length) => {
|
|
991
|
+
if (length < 0) {
|
|
992
|
+
throw new Error('runtime error: unsafe slice length out of range');
|
|
993
|
+
}
|
|
994
|
+
return goSlice(collection, index, index + length, index + length);
|
|
995
|
+
},
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
export function sliceFromOwnedPointer(pointer, length) {
|
|
999
|
+
if (!isOwnedPointerHandle(pointer) || pointer.__goSlice === undefined) {
|
|
1000
|
+
throw new Error('reflect.SliceAt requires a GoScript-owned pointer');
|
|
1001
|
+
}
|
|
1002
|
+
return pointer.__goSlice(length);
|
|
1003
|
+
}
|
|
979
1004
|
/**
|
|
980
1005
|
* arrayPointerFromIndexRef turns &slice[i] into a pointer to an N-element array
|
|
981
1006
|
* view. This models unsafe conversions such as (*[64]byte)(unsafe.Pointer(&b[0]))
|