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
|
@@ -5,6 +5,7 @@ import (
|
|
|
5
5
|
"os"
|
|
6
6
|
"path/filepath"
|
|
7
7
|
"slices"
|
|
8
|
+
"strconv"
|
|
8
9
|
"strings"
|
|
9
10
|
"testing"
|
|
10
11
|
)
|
|
@@ -80,6 +81,17 @@ func TestOverrideRegistryFactsAreImmutable(t *testing.T) {
|
|
|
80
81
|
if len(pkg.files) == 0 || pkg.files[0].data[0] == '!' {
|
|
81
82
|
t.Fatalf("copy file mutation leaked back into facts")
|
|
82
83
|
}
|
|
84
|
+
|
|
85
|
+
ledger := facts.parityLedger("net/http")
|
|
86
|
+
if got := ledger.Symbols["ServeFile"].Status; got != overrideParityStatusReal {
|
|
87
|
+
t.Fatalf("expected net/http ServeFile real parity, got %q", got)
|
|
88
|
+
}
|
|
89
|
+
ledger.Symbols["ServeFile"] = overrideParityEntry{Status: overrideParityStatusDeferred}
|
|
90
|
+
|
|
91
|
+
ledger = facts.parityLedger("net/http")
|
|
92
|
+
if got := ledger.Symbols["ServeFile"].Status; got != overrideParityStatusReal {
|
|
93
|
+
t.Fatalf("parity ledger mutation leaked back into facts: %q", got)
|
|
94
|
+
}
|
|
83
95
|
}
|
|
84
96
|
|
|
85
97
|
func TestOverrideRegistryCopiesRuntimeAndOverrides(t *testing.T) {
|
|
@@ -384,6 +396,51 @@ func TestCompilePackagesAwaitsOverrideAsyncInterfaceMethodCalls(t *testing.T) {
|
|
|
384
396
|
}
|
|
385
397
|
}
|
|
386
398
|
|
|
399
|
+
func TestCompilePackagesAwaitsNetHTTPServeHTTPOverrideMethods(t *testing.T) {
|
|
400
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
401
|
+
"go.mod": "module example.test/httpserveasync\n\ngo 1.25.3\n",
|
|
402
|
+
"main.go": strings.Join([]string{
|
|
403
|
+
"package main",
|
|
404
|
+
"import \"net/http\"",
|
|
405
|
+
"func Use(h http.Handler, hf http.HandlerFunc, mux *http.ServeMux, w http.ResponseWriter, r *http.Request) {",
|
|
406
|
+
" h.ServeHTTP(w, r)",
|
|
407
|
+
" hf.ServeHTTP(w, r)",
|
|
408
|
+
" mux.ServeHTTP(w, r)",
|
|
409
|
+
"}",
|
|
410
|
+
"func main() {}",
|
|
411
|
+
"",
|
|
412
|
+
}, "\n"),
|
|
413
|
+
})
|
|
414
|
+
out := filepath.Join(t.TempDir(), "out")
|
|
415
|
+
comp, err := NewCompiler(&Config{
|
|
416
|
+
Dir: moduleDir,
|
|
417
|
+
OutputPath: out,
|
|
418
|
+
AllDependencies: true,
|
|
419
|
+
}, nil, nil)
|
|
420
|
+
if err != nil {
|
|
421
|
+
t.Fatal(err.Error())
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
|
|
425
|
+
t.Fatal(err.Error())
|
|
426
|
+
}
|
|
427
|
+
content, err := os.ReadFile(filepath.Join(out, "@goscript", "example.test", "httpserveasync", "main.gs.ts"))
|
|
428
|
+
if err != nil {
|
|
429
|
+
t.Fatal(err.Error())
|
|
430
|
+
}
|
|
431
|
+
text := string(content)
|
|
432
|
+
for _, want := range []string{
|
|
433
|
+
"export async function Use(",
|
|
434
|
+
"await $.pointerValue<Exclude<http.Handler, null>>(h).ServeHTTP($.pointerValueOrNil(w)!, r)",
|
|
435
|
+
"await http.HandlerFunc_ServeHTTP(hf, $.pointerValueOrNil(w)!, r)",
|
|
436
|
+
"await http.ServeMux.prototype.ServeHTTP.call($.pointerValue<http.ServeMux>(mux), $.pointerValueOrNil(w)!, r)",
|
|
437
|
+
} {
|
|
438
|
+
if !strings.Contains(text, want) {
|
|
439
|
+
t.Fatalf("missing %q in generated output:\n%s", want, text)
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
387
444
|
func TestCompilePackagesAwaitsOverrideAsyncFunctions(t *testing.T) {
|
|
388
445
|
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
389
446
|
"go.mod": "module example.test/overrideasyncfunc\n\ngo 1.25.3\n",
|
|
@@ -430,3 +487,505 @@ func TestCompilePackagesAwaitsOverrideAsyncFunctions(t *testing.T) {
|
|
|
430
487
|
t.Fatalf("walk callback was not lowered as async:\n%s", string(content))
|
|
431
488
|
}
|
|
432
489
|
}
|
|
490
|
+
|
|
491
|
+
func TestCompilePackagesAwaitsReflectValueCall(t *testing.T) {
|
|
492
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
493
|
+
"go.mod": "module example.test/reflectcallasync\n\ngo 1.25.3\n",
|
|
494
|
+
"main.go": strings.Join([]string{
|
|
495
|
+
"package main",
|
|
496
|
+
"import \"reflect\"",
|
|
497
|
+
"func Use(fn func()) []reflect.Value {",
|
|
498
|
+
" return reflect.ValueOf(fn).Call(nil)",
|
|
499
|
+
"}",
|
|
500
|
+
"func UseSlice(fn func(...int), args []reflect.Value) []reflect.Value {",
|
|
501
|
+
" return reflect.ValueOf(fn).CallSlice(args)",
|
|
502
|
+
"}",
|
|
503
|
+
"",
|
|
504
|
+
}, "\n"),
|
|
505
|
+
})
|
|
506
|
+
out := filepath.Join(t.TempDir(), "out")
|
|
507
|
+
comp, err := NewCompiler(&Config{
|
|
508
|
+
Dir: moduleDir,
|
|
509
|
+
OutputPath: out,
|
|
510
|
+
AllDependencies: true,
|
|
511
|
+
}, nil, nil)
|
|
512
|
+
if err != nil {
|
|
513
|
+
t.Fatal(err.Error())
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
|
|
517
|
+
t.Fatal(err.Error())
|
|
518
|
+
}
|
|
519
|
+
content, err := os.ReadFile(filepath.Join(out, "@goscript", "example.test", "reflectcallasync", "main.gs.ts"))
|
|
520
|
+
if err != nil {
|
|
521
|
+
t.Fatal(err.Error())
|
|
522
|
+
}
|
|
523
|
+
text := string(content)
|
|
524
|
+
if !strings.Contains(text, "export async function Use") {
|
|
525
|
+
t.Fatalf("reflect.Value.Call caller was not marked async:\n%s", text)
|
|
526
|
+
}
|
|
527
|
+
if !strings.Contains(text, "return await ") || !strings.Contains(text, ".Call(null)") {
|
|
528
|
+
t.Fatalf("reflect.Value.Call was not awaited:\n%s", text)
|
|
529
|
+
}
|
|
530
|
+
if !strings.Contains(text, "export async function UseSlice") {
|
|
531
|
+
t.Fatalf("reflect.Value.CallSlice caller was not marked async:\n%s", text)
|
|
532
|
+
}
|
|
533
|
+
if !strings.Contains(text, "return await ") || !strings.Contains(text, ".CallSlice(args)") {
|
|
534
|
+
t.Fatalf("reflect.Value.CallSlice was not awaited:\n%s", text)
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
func TestOverrideParityVerifierResolvesEffectiveTypeScriptExports(t *testing.T) {
|
|
539
|
+
files := map[string]string{
|
|
540
|
+
"example.test/lib/index.ts": strings.Join([]string{
|
|
541
|
+
"export { RenamedSource as Renamed } from './named.js'",
|
|
542
|
+
"export type { TypeShape } from './types.js'",
|
|
543
|
+
"export * from './star.js'",
|
|
544
|
+
"",
|
|
545
|
+
}, "\n"),
|
|
546
|
+
"example.test/lib/named.ts": "export function RenamedSource(): void {}\n",
|
|
547
|
+
"example.test/lib/star.ts": "export class Star {}\n",
|
|
548
|
+
"example.test/lib/types.ts": "export interface TypeShape {}\n",
|
|
549
|
+
}
|
|
550
|
+
exports := make(map[string]typeScriptExport)
|
|
551
|
+
if err := collectTypeScriptExports("example.test/lib/index.ts", files, exports, make(map[string]bool)); err != nil {
|
|
552
|
+
t.Fatal(err.Error())
|
|
553
|
+
}
|
|
554
|
+
for _, name := range []string{"Renamed", "TypeShape", "Star"} {
|
|
555
|
+
if !exports[name].present() {
|
|
556
|
+
t.Fatalf("effective TypeScript exports missing %s: %v", name, exports)
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
if exports["RenamedSource"].present() {
|
|
560
|
+
t.Fatalf("named re-export source leaked into effective exports: %v", exports)
|
|
561
|
+
}
|
|
562
|
+
if !exports["Renamed"].value || exports["Renamed"].typ {
|
|
563
|
+
t.Fatalf("renamed function export should be value-only: %#v", exports["Renamed"])
|
|
564
|
+
}
|
|
565
|
+
if !exports["TypeShape"].typ || exports["TypeShape"].value {
|
|
566
|
+
t.Fatalf("type re-export should be type-only: %#v", exports["TypeShape"])
|
|
567
|
+
}
|
|
568
|
+
if !exports["Star"].value || !exports["Star"].typ {
|
|
569
|
+
t.Fatalf("class star export should carry value and type shapes: %#v", exports["Star"])
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
func TestOverrideParityVerifierValidatesNamedReExportSources(t *testing.T) {
|
|
574
|
+
files := map[string]string{
|
|
575
|
+
"example.test/lib/index.ts": "export { Missing } from './named.js'\n",
|
|
576
|
+
"example.test/lib/named.ts": "export function Present(): void {}\n",
|
|
577
|
+
}
|
|
578
|
+
err := collectTypeScriptExports("example.test/lib/index.ts", files, make(map[string]typeScriptExport), make(map[string]bool))
|
|
579
|
+
if err == nil {
|
|
580
|
+
t.Fatalf("expected missing named re-export source to fail")
|
|
581
|
+
}
|
|
582
|
+
if !strings.Contains(err.Error(), "re-exports missing symbol Missing") {
|
|
583
|
+
t.Fatalf("unexpected error: %v", err)
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
func TestOverrideParityVerifierValidatesLocalNamedExportSources(t *testing.T) {
|
|
588
|
+
files := map[string]string{
|
|
589
|
+
"example.test/lib/index.ts": "export { Missing }\n",
|
|
590
|
+
}
|
|
591
|
+
err := collectTypeScriptExports("example.test/lib/index.ts", files, make(map[string]typeScriptExport), make(map[string]bool))
|
|
592
|
+
if err == nil {
|
|
593
|
+
t.Fatalf("expected missing local named export source to fail")
|
|
594
|
+
}
|
|
595
|
+
if !strings.Contains(err.Error(), "exports missing local value symbol Missing") {
|
|
596
|
+
t.Fatalf("unexpected error: %v", err)
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
func TestOverrideParityVerifierReportsStrictUnclassifiedSymbol(t *testing.T) {
|
|
601
|
+
result, err := compileParityFixture(t, map[string]overrideParityEntry{
|
|
602
|
+
"Present": {Status: overrideParityStatusReal},
|
|
603
|
+
}, "export function Present(): void {}\n")
|
|
604
|
+
if err == nil {
|
|
605
|
+
t.Fatalf("expected compile to fail")
|
|
606
|
+
}
|
|
607
|
+
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-unclassified")
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
func TestOverrideParityVerifierReportsMissingTypeScriptExport(t *testing.T) {
|
|
611
|
+
result, err := compileParityFixture(t, map[string]overrideParityEntry{
|
|
612
|
+
"Present": {Status: overrideParityStatusReal},
|
|
613
|
+
"Missing": {Status: overrideParityStatusReal},
|
|
614
|
+
}, "export function Present(): void {}\n")
|
|
615
|
+
if err == nil {
|
|
616
|
+
t.Fatalf("expected compile to fail")
|
|
617
|
+
}
|
|
618
|
+
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-missing-export")
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
func TestOverrideParityVerifierRejectsTypeOnlyValueExport(t *testing.T) {
|
|
622
|
+
result, err := compileParityFixture(t, map[string]overrideParityEntry{
|
|
623
|
+
"Present": {Status: overrideParityStatusReal},
|
|
624
|
+
"Missing": {Status: overrideParityStatusReal},
|
|
625
|
+
}, strings.Join([]string{
|
|
626
|
+
"export function Present(): void {}",
|
|
627
|
+
"export type Missing = unknown",
|
|
628
|
+
"",
|
|
629
|
+
}, "\n"))
|
|
630
|
+
if err == nil {
|
|
631
|
+
t.Fatalf("expected compile to fail")
|
|
632
|
+
}
|
|
633
|
+
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-missing-export")
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
func TestOverrideParityVerifierRejectsTypeOnlyStructExport(t *testing.T) {
|
|
637
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
638
|
+
"go.mod": "module example.test/structparity\n\ngo 1.25.3\n",
|
|
639
|
+
"main.go": strings.Join([]string{
|
|
640
|
+
"package main",
|
|
641
|
+
"import \"example.test/structparity/lib\"",
|
|
642
|
+
"func main() { _ = lib.StructExport{} }",
|
|
643
|
+
"",
|
|
644
|
+
}, "\n"),
|
|
645
|
+
"lib/lib.go": strings.Join([]string{
|
|
646
|
+
"package lib",
|
|
647
|
+
"type StructExport struct{}",
|
|
648
|
+
"",
|
|
649
|
+
}, "\n"),
|
|
650
|
+
})
|
|
651
|
+
overrideDir := filepath.Join(t.TempDir(), "gs")
|
|
652
|
+
writeFixtureFile(t, overrideDir, "example.test/structparity/lib/index.ts", "export type StructExport = {}\n")
|
|
653
|
+
writeFixtureFile(t, overrideDir, "example.test/structparity/lib/parity.json", parityFixtureJSON(t, map[string]overrideParityEntry{
|
|
654
|
+
"StructExport": {Status: overrideParityStatusReal},
|
|
655
|
+
}))
|
|
656
|
+
|
|
657
|
+
comp, err := NewCompiler(&Config{
|
|
658
|
+
Dir: moduleDir,
|
|
659
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
660
|
+
OverrideDirs: []string{overrideDir},
|
|
661
|
+
AllDependencies: true,
|
|
662
|
+
}, nil, nil)
|
|
663
|
+
if err != nil {
|
|
664
|
+
t.Fatal(err.Error())
|
|
665
|
+
}
|
|
666
|
+
result, err := comp.CompilePackages(context.Background(), ".")
|
|
667
|
+
if err == nil {
|
|
668
|
+
t.Fatalf("expected compile to fail")
|
|
669
|
+
}
|
|
670
|
+
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-missing-export")
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
func TestOverrideParityVerifierReportsBlockedTypeScriptExport(t *testing.T) {
|
|
674
|
+
result, err := compileParityFixture(t, map[string]overrideParityEntry{
|
|
675
|
+
"Present": {Status: overrideParityStatusReal},
|
|
676
|
+
"Missing": {Status: overrideParityStatusBlocked, Reason: "blocked by fixture"},
|
|
677
|
+
}, strings.Join([]string{
|
|
678
|
+
"export function Present(): void {}",
|
|
679
|
+
"export function Missing(): void {}",
|
|
680
|
+
"",
|
|
681
|
+
}, "\n"))
|
|
682
|
+
if err == nil {
|
|
683
|
+
t.Fatalf("expected compile to fail")
|
|
684
|
+
}
|
|
685
|
+
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-unexpected-export")
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
func TestOverrideParityVerifierReportsBlockedGoUse(t *testing.T) {
|
|
689
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
690
|
+
"go.mod": "module example.test/blockeduse\n\ngo 1.25.3\n",
|
|
691
|
+
"main.go": strings.Join([]string{
|
|
692
|
+
"package main",
|
|
693
|
+
"import \"example.test/blockeduse/lib\"",
|
|
694
|
+
"func main() { lib.Missing() }",
|
|
695
|
+
"",
|
|
696
|
+
}, "\n"),
|
|
697
|
+
"lib/lib.go": strings.Join([]string{
|
|
698
|
+
"package lib",
|
|
699
|
+
"func Present() {}",
|
|
700
|
+
"func Missing() {}",
|
|
701
|
+
"",
|
|
702
|
+
}, "\n"),
|
|
703
|
+
})
|
|
704
|
+
overrideDir := filepath.Join(t.TempDir(), "gs")
|
|
705
|
+
writeFixtureFile(t, overrideDir, "example.test/blockeduse/lib/index.ts", "export function Present(): void {}\n")
|
|
706
|
+
writeFixtureFile(t, overrideDir, "example.test/blockeduse/lib/parity.json", parityFixtureJSON(t, map[string]overrideParityEntry{
|
|
707
|
+
"Present": {Status: overrideParityStatusReal},
|
|
708
|
+
"Missing": {Status: overrideParityStatusBlocked, Reason: "blocked by fixture"},
|
|
709
|
+
}))
|
|
710
|
+
|
|
711
|
+
comp, err := NewCompiler(&Config{
|
|
712
|
+
Dir: moduleDir,
|
|
713
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
714
|
+
OverrideDirs: []string{overrideDir},
|
|
715
|
+
AllDependencies: true,
|
|
716
|
+
}, nil, nil)
|
|
717
|
+
if err != nil {
|
|
718
|
+
t.Fatal(err.Error())
|
|
719
|
+
}
|
|
720
|
+
result, err := comp.CompilePackages(context.Background(), ".")
|
|
721
|
+
if err == nil {
|
|
722
|
+
t.Fatalf("expected compile to fail")
|
|
723
|
+
}
|
|
724
|
+
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-blocked-use")
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
func TestOverrideParityVerifierAllowsDeferredMissingExports(t *testing.T) {
|
|
728
|
+
result, err := compileParityFixture(t, map[string]overrideParityEntry{
|
|
729
|
+
"Present": {Status: overrideParityStatusReal},
|
|
730
|
+
"Missing": {Status: overrideParityStatusDeferred},
|
|
731
|
+
}, "export function Present(): void {}\n")
|
|
732
|
+
if err != nil {
|
|
733
|
+
t.Fatalf("compile failed: %v\n%#v", err, result.Diagnostics)
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
func TestOverrideParityVerifierReportsDeferredAtPhaseClose(t *testing.T) {
|
|
738
|
+
owner := NewOverrideRegistryOwner()
|
|
739
|
+
facts, diagnostics := owner.Facts(context.Background())
|
|
740
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
741
|
+
t.Fatalf("override facts failed: %#v", diagnostics)
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
diagnostics = NewOverrideParityVerifier().VerifyNoDeferred(facts,
|
|
745
|
+
"net/http",
|
|
746
|
+
"net/http/httptest",
|
|
747
|
+
"encoding/json",
|
|
748
|
+
"mime",
|
|
749
|
+
"time",
|
|
750
|
+
"reflect",
|
|
751
|
+
"math/bits",
|
|
752
|
+
"strings",
|
|
753
|
+
"strconv",
|
|
754
|
+
"compress/zlib",
|
|
755
|
+
"io",
|
|
756
|
+
"go/scanner",
|
|
757
|
+
"hash",
|
|
758
|
+
"internal/goarch",
|
|
759
|
+
"os",
|
|
760
|
+
"runtime",
|
|
761
|
+
"runtime/pprof",
|
|
762
|
+
"runtime/trace",
|
|
763
|
+
)
|
|
764
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
765
|
+
t.Fatalf("override ledgers still contain deferred entries: %#v", diagnostics)
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
func TestOverrideParityVerifierAcceptsPhase4Ledgers(t *testing.T) {
|
|
770
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
771
|
+
"go.mod": "module example.test/phase4parity\n\ngo 1.25.3\n",
|
|
772
|
+
"main.go": strings.Join([]string{
|
|
773
|
+
"package main",
|
|
774
|
+
"import (",
|
|
775
|
+
" \"compress/zlib\"",
|
|
776
|
+
" \"encoding/json\"",
|
|
777
|
+
" \"go/scanner\"",
|
|
778
|
+
" \"hash\"",
|
|
779
|
+
" \"io\"",
|
|
780
|
+
" \"math/bits\"",
|
|
781
|
+
" \"mime\"",
|
|
782
|
+
" \"os\"",
|
|
783
|
+
" \"reflect\"",
|
|
784
|
+
" \"strconv\"",
|
|
785
|
+
" \"strings\"",
|
|
786
|
+
" \"time\"",
|
|
787
|
+
")",
|
|
788
|
+
"var _ = json.Valid",
|
|
789
|
+
"var _ = mime.TypeByExtension",
|
|
790
|
+
"var _ = time.RFC1123",
|
|
791
|
+
"var _ = reflect.VisibleFields",
|
|
792
|
+
"var _ = bits.Rem32",
|
|
793
|
+
"var _ = strings.ToValidUTF8",
|
|
794
|
+
"var _ = strconv.FormatComplex",
|
|
795
|
+
"var _ = zlib.NoCompression",
|
|
796
|
+
"var _ io.ReadSeekCloser",
|
|
797
|
+
"var _ = scanner.PrintError",
|
|
798
|
+
"var _ hash.XOF",
|
|
799
|
+
"var _ = os.ErrNoHandle",
|
|
800
|
+
"func main() {}",
|
|
801
|
+
"",
|
|
802
|
+
}, "\n"),
|
|
803
|
+
})
|
|
804
|
+
comp, err := NewCompiler(&Config{
|
|
805
|
+
Dir: moduleDir,
|
|
806
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
807
|
+
AllDependencies: true,
|
|
808
|
+
}, nil, nil)
|
|
809
|
+
if err != nil {
|
|
810
|
+
t.Fatal(err.Error())
|
|
811
|
+
}
|
|
812
|
+
result, err := comp.CompilePackages(context.Background(), ".")
|
|
813
|
+
if err != nil {
|
|
814
|
+
t.Fatalf("compile failed: %v\n%#v", err, result.Diagnostics)
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
func TestOverrideParityVerifierAllowsRealFuncOfUse(t *testing.T) {
|
|
819
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
820
|
+
"go.mod": "module example.test/funcparity\n\ngo 1.25.3\n",
|
|
821
|
+
"main.go": strings.Join([]string{
|
|
822
|
+
"package main",
|
|
823
|
+
"import \"reflect\"",
|
|
824
|
+
"func main() {",
|
|
825
|
+
" _ = reflect.FuncOf(nil, nil, false)",
|
|
826
|
+
"}",
|
|
827
|
+
"",
|
|
828
|
+
}, "\n"),
|
|
829
|
+
})
|
|
830
|
+
comp, err := NewCompiler(&Config{
|
|
831
|
+
Dir: moduleDir,
|
|
832
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
833
|
+
AllDependencies: true,
|
|
834
|
+
}, nil, nil)
|
|
835
|
+
if err != nil {
|
|
836
|
+
t.Fatal(err.Error())
|
|
837
|
+
}
|
|
838
|
+
result, err := comp.CompilePackages(context.Background(), ".")
|
|
839
|
+
if err != nil {
|
|
840
|
+
t.Fatalf("expected reflect.FuncOf use to compile: %v\n%#v", err, result.Diagnostics)
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
func TestOverrideParityVerifierAllowsRealMakeFuncUse(t *testing.T) {
|
|
845
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
846
|
+
"go.mod": "module example.test/makefuncparity\n\ngo 1.25.3\n",
|
|
847
|
+
"main.go": strings.Join([]string{
|
|
848
|
+
"package main",
|
|
849
|
+
"import \"reflect\"",
|
|
850
|
+
"func main() {",
|
|
851
|
+
" typ := reflect.FuncOf(nil, nil, false)",
|
|
852
|
+
" _ = reflect.MakeFunc(typ, func(args []reflect.Value) []reflect.Value { return nil })",
|
|
853
|
+
"}",
|
|
854
|
+
"",
|
|
855
|
+
}, "\n"),
|
|
856
|
+
})
|
|
857
|
+
comp, err := NewCompiler(&Config{
|
|
858
|
+
Dir: moduleDir,
|
|
859
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
860
|
+
AllDependencies: true,
|
|
861
|
+
}, nil, nil)
|
|
862
|
+
if err != nil {
|
|
863
|
+
t.Fatal(err.Error())
|
|
864
|
+
}
|
|
865
|
+
result, err := comp.CompilePackages(context.Background(), ".")
|
|
866
|
+
if err != nil {
|
|
867
|
+
t.Fatalf("expected reflect.MakeFunc use to compile: %v\n%#v", err, result.Diagnostics)
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
func TestOverrideParityVerifierAllowsRealStructOfUse(t *testing.T) {
|
|
872
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
873
|
+
"go.mod": "module example.test/structofparity\n\ngo 1.25.3\n",
|
|
874
|
+
"main.go": strings.Join([]string{
|
|
875
|
+
"package main",
|
|
876
|
+
"import \"reflect\"",
|
|
877
|
+
"func main() {",
|
|
878
|
+
" _ = reflect.StructOf([]reflect.StructField{{Name: \"Count\", Type: reflect.TypeFor[int]()}})",
|
|
879
|
+
"}",
|
|
880
|
+
"",
|
|
881
|
+
}, "\n"),
|
|
882
|
+
})
|
|
883
|
+
comp, err := NewCompiler(&Config{
|
|
884
|
+
Dir: moduleDir,
|
|
885
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
886
|
+
AllDependencies: true,
|
|
887
|
+
}, nil, nil)
|
|
888
|
+
if err != nil {
|
|
889
|
+
t.Fatal(err.Error())
|
|
890
|
+
}
|
|
891
|
+
result, err := comp.CompilePackages(context.Background(), ".")
|
|
892
|
+
if err != nil {
|
|
893
|
+
t.Fatalf("expected reflect.StructOf use to compile: %v\n%#v", err, result.Diagnostics)
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
func TestOverrideParityVerifierAllowsRealSliceAtUse(t *testing.T) {
|
|
898
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
899
|
+
"go.mod": "module example.test/sliceatparity\n\ngo 1.25.3\n",
|
|
900
|
+
"main.go": strings.Join([]string{
|
|
901
|
+
"package main",
|
|
902
|
+
"import (",
|
|
903
|
+
" \"reflect\"",
|
|
904
|
+
" \"unsafe\"",
|
|
905
|
+
")",
|
|
906
|
+
"func main() {",
|
|
907
|
+
" buf := []byte{1, 2, 3}",
|
|
908
|
+
" _ = reflect.SliceAt(reflect.TypeFor[byte](), unsafe.Pointer(&buf[0]), len(buf))",
|
|
909
|
+
"}",
|
|
910
|
+
"",
|
|
911
|
+
}, "\n"),
|
|
912
|
+
})
|
|
913
|
+
comp, err := NewCompiler(&Config{
|
|
914
|
+
Dir: moduleDir,
|
|
915
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
916
|
+
AllDependencies: true,
|
|
917
|
+
}, nil, nil)
|
|
918
|
+
if err != nil {
|
|
919
|
+
t.Fatal(err.Error())
|
|
920
|
+
}
|
|
921
|
+
result, err := comp.CompilePackages(context.Background(), ".")
|
|
922
|
+
if err != nil {
|
|
923
|
+
t.Fatalf("expected reflect.SliceAt use to compile: %v\n%#v", err, result.Diagnostics)
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
func compileParityFixture(
|
|
928
|
+
t *testing.T,
|
|
929
|
+
symbols map[string]overrideParityEntry,
|
|
930
|
+
index string,
|
|
931
|
+
) (*CompilationResult, error) {
|
|
932
|
+
t.Helper()
|
|
933
|
+
|
|
934
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
935
|
+
"go.mod": "module example.test/parity\n\ngo 1.25.3\n",
|
|
936
|
+
"main.go": strings.Join([]string{
|
|
937
|
+
"package main",
|
|
938
|
+
"import \"example.test/parity/lib\"",
|
|
939
|
+
"func main() { lib.Present() }",
|
|
940
|
+
"",
|
|
941
|
+
}, "\n"),
|
|
942
|
+
"lib/lib.go": strings.Join([]string{
|
|
943
|
+
"package lib",
|
|
944
|
+
"func Present() {}",
|
|
945
|
+
"func Missing() {}",
|
|
946
|
+
"",
|
|
947
|
+
}, "\n"),
|
|
948
|
+
})
|
|
949
|
+
overrideDir := filepath.Join(t.TempDir(), "gs")
|
|
950
|
+
writeFixtureFile(t, overrideDir, "example.test/parity/lib/index.ts", index)
|
|
951
|
+
writeFixtureFile(t, overrideDir, "example.test/parity/lib/parity.json", parityFixtureJSON(t, symbols))
|
|
952
|
+
|
|
953
|
+
comp, err := NewCompiler(&Config{
|
|
954
|
+
Dir: moduleDir,
|
|
955
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
956
|
+
OverrideDirs: []string{overrideDir},
|
|
957
|
+
AllDependencies: true,
|
|
958
|
+
}, nil, nil)
|
|
959
|
+
if err != nil {
|
|
960
|
+
t.Fatal(err.Error())
|
|
961
|
+
}
|
|
962
|
+
return comp.CompilePackages(context.Background(), ".")
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
func parityFixtureJSON(t *testing.T, symbols map[string]overrideParityEntry) string {
|
|
966
|
+
t.Helper()
|
|
967
|
+
|
|
968
|
+
var b strings.Builder
|
|
969
|
+
b.WriteString("{\"schemaVersion\":1,\"strict\":true,\"symbols\":{")
|
|
970
|
+
names := make([]string, 0, len(symbols))
|
|
971
|
+
for name := range symbols {
|
|
972
|
+
names = append(names, name)
|
|
973
|
+
}
|
|
974
|
+
slices.Sort(names)
|
|
975
|
+
for idx, name := range names {
|
|
976
|
+
if idx != 0 {
|
|
977
|
+
b.WriteByte(',')
|
|
978
|
+
}
|
|
979
|
+
entry := symbols[name]
|
|
980
|
+
b.WriteString(strconv.Quote(name))
|
|
981
|
+
b.WriteString(":{\"status\":")
|
|
982
|
+
b.WriteString(strconv.Quote(string(entry.Status)))
|
|
983
|
+
if entry.Reason != "" {
|
|
984
|
+
b.WriteString(",\"reason\":")
|
|
985
|
+
b.WriteString(strconv.Quote(entry.Reason))
|
|
986
|
+
}
|
|
987
|
+
b.WriteString("}")
|
|
988
|
+
}
|
|
989
|
+
b.WriteString("}}\n")
|
|
990
|
+
return b.String()
|
|
991
|
+
}
|
|
@@ -2,6 +2,7 @@ package compiler
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"context"
|
|
5
|
+
"go/ast"
|
|
5
6
|
"os"
|
|
6
7
|
"slices"
|
|
7
8
|
"strings"
|
|
@@ -130,6 +131,15 @@ func (o *PackageGraphOwner) Load(ctx context.Context, req *CompileRequest) (*Pac
|
|
|
130
131
|
graph.RequestedPackagePaths = append(graph.RequestedPackagePaths, path)
|
|
131
132
|
}
|
|
132
133
|
slices.Sort(graph.RequestedPackagePaths)
|
|
134
|
+
samePackageTestVariants := make(map[string]bool)
|
|
135
|
+
if req.Tests {
|
|
136
|
+
for _, pkg := range pkgs {
|
|
137
|
+
if pkg == nil || pkg.ForTest == "" || strings.HasSuffix(pkg.Name, "_test") {
|
|
138
|
+
continue
|
|
139
|
+
}
|
|
140
|
+
samePackageTestVariants[pkg.ForTest] = true
|
|
141
|
+
}
|
|
142
|
+
}
|
|
133
143
|
|
|
134
144
|
var diagnostics []Diagnostic
|
|
135
145
|
seen := make(map[string]bool)
|
|
@@ -137,7 +147,7 @@ func (o *PackageGraphOwner) Load(ctx context.Context, req *CompileRequest) (*Pac
|
|
|
137
147
|
if isTestMainPackage(pkg) {
|
|
138
148
|
continue
|
|
139
149
|
}
|
|
140
|
-
o.collect(graph, pkg, req.DependencyMode, requested, overrideFacts, seen)
|
|
150
|
+
o.collect(graph, pkg, req.DependencyMode, requested, samePackageTestVariants, overrideFacts, seen)
|
|
141
151
|
diagnostics = append(diagnostics, packageDiagnostics(pkg)...)
|
|
142
152
|
}
|
|
143
153
|
slices.SortFunc(graph.Nodes, func(a, b *PackageGraphNode) int {
|
|
@@ -161,21 +171,33 @@ func (o *PackageGraphOwner) collect(
|
|
|
161
171
|
pkg *packages.Package,
|
|
162
172
|
mode DependencyMode,
|
|
163
173
|
requested map[string]bool,
|
|
174
|
+
samePackageTestVariants map[string]bool,
|
|
164
175
|
overrideFacts *OverrideFacts,
|
|
165
176
|
seen map[string]bool,
|
|
166
177
|
) {
|
|
167
178
|
if pkg == nil || seen[pkg.ID] {
|
|
168
179
|
return
|
|
169
180
|
}
|
|
181
|
+
path := packagePath(pkg)
|
|
182
|
+
if pkg.ForTest != "" && path != pkg.ForTest && !strings.HasSuffix(pkg.Name, "_test") && samePackageTestVariants[path] {
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
if pkg.ForTest == "" && samePackageTestVariants[path] {
|
|
186
|
+
return
|
|
187
|
+
}
|
|
170
188
|
if pkg.ForTest != "" && !requested[pkg.ForTest] {
|
|
171
189
|
if prod := pkg.Imports[pkg.ForTest]; prod != nil {
|
|
172
|
-
o.collect(graph, prod, mode, requested, overrideFacts, seen)
|
|
190
|
+
o.collect(graph, prod, mode, requested, samePackageTestVariants, overrideFacts, seen)
|
|
173
191
|
}
|
|
174
192
|
return
|
|
175
193
|
}
|
|
194
|
+
if graph.NodesByPackagePath[path] != nil {
|
|
195
|
+
return
|
|
196
|
+
}
|
|
176
197
|
seen[pkg.ID] = true
|
|
177
198
|
|
|
178
|
-
|
|
199
|
+
normalizePackageFileOrder(pkg)
|
|
200
|
+
|
|
179
201
|
node := newPackageGraphNode(pkg, requested[path], overrideFacts)
|
|
180
202
|
graph.Nodes = append(graph.Nodes, node)
|
|
181
203
|
graph.NodesByPackagePath[path] = node
|
|
@@ -190,7 +212,7 @@ func (o *PackageGraphOwner) collect(
|
|
|
190
212
|
}
|
|
191
213
|
slices.Sort(imports)
|
|
192
214
|
for _, importPath := range imports {
|
|
193
|
-
o.collect(graph, pkg.Imports[importPath], mode, requested, overrideFacts, seen)
|
|
215
|
+
o.collect(graph, pkg.Imports[importPath], mode, requested, samePackageTestVariants, overrideFacts, seen)
|
|
194
216
|
}
|
|
195
217
|
}
|
|
196
218
|
|
|
@@ -223,6 +245,41 @@ func newPackageGraphNode(pkg *packages.Package, requested bool, overrideFacts *O
|
|
|
223
245
|
}
|
|
224
246
|
}
|
|
225
247
|
|
|
248
|
+
func normalizePackageFileOrder(pkg *packages.Package) {
|
|
249
|
+
if pkg == nil {
|
|
250
|
+
return
|
|
251
|
+
}
|
|
252
|
+
slices.Sort(pkg.GoFiles)
|
|
253
|
+
if len(pkg.Syntax) == len(pkg.CompiledGoFiles) {
|
|
254
|
+
type sourceFile struct {
|
|
255
|
+
name string
|
|
256
|
+
file *ast.File
|
|
257
|
+
}
|
|
258
|
+
files := make([]sourceFile, len(pkg.Syntax))
|
|
259
|
+
for idx, file := range pkg.Syntax {
|
|
260
|
+
files[idx] = sourceFile{name: pkg.CompiledGoFiles[idx], file: file}
|
|
261
|
+
}
|
|
262
|
+
slices.SortFunc(files, func(a, b sourceFile) int {
|
|
263
|
+
return strings.Compare(a.name, b.name)
|
|
264
|
+
})
|
|
265
|
+
for idx, file := range files {
|
|
266
|
+
pkg.CompiledGoFiles[idx] = file.name
|
|
267
|
+
pkg.Syntax[idx] = file.file
|
|
268
|
+
}
|
|
269
|
+
return
|
|
270
|
+
}
|
|
271
|
+
slices.Sort(pkg.CompiledGoFiles)
|
|
272
|
+
slices.SortFunc(pkg.Syntax, func(a, b *ast.File) int {
|
|
273
|
+
if pkg.Fset == nil {
|
|
274
|
+
return strings.Compare(a.Name.Name, b.Name.Name)
|
|
275
|
+
}
|
|
276
|
+
return strings.Compare(
|
|
277
|
+
pkg.Fset.Position(a.Package).Filename,
|
|
278
|
+
pkg.Fset.Position(b.Package).Filename,
|
|
279
|
+
)
|
|
280
|
+
})
|
|
281
|
+
}
|
|
282
|
+
|
|
226
283
|
func isTestMainPackage(pkg *packages.Package) bool {
|
|
227
284
|
return pkg != nil && pkg.ForTest == "" && pkg.Name == "main" && strings.HasSuffix(packagePath(pkg), ".test")
|
|
228
285
|
}
|