goscript 0.1.1 → 0.1.2
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/cmd/goscript/cmd-test.go +104 -11
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript/cmd_compile.go +9 -0
- package/compiler/compile-request.go +31 -0
- package/compiler/compiler.go +1 -1
- package/compiler/compliance_test.go +0 -2
- package/compiler/config.go +2 -0
- package/compiler/gotest/package-result.go +2 -0
- package/compiler/gotest/request.go +85 -20
- package/compiler/gotest/runner.go +733 -96
- package/compiler/gotest/runner_test.go +647 -3
- package/compiler/lowered-program.go +9 -2
- package/compiler/lowering.go +2001 -345
- package/compiler/override-facts.go +77 -27
- package/compiler/override-registry.go +5 -4
- package/compiler/override-registry_test.go +135 -0
- package/compiler/package-graph_test.go +62 -7
- package/compiler/package-test-graph-variant.go +40 -16
- package/compiler/package-test-graph.go +0 -5
- package/compiler/package-test-graph_test.go +61 -3
- package/compiler/runtime-contract.go +40 -0
- package/compiler/semantic-model-types.go +16 -0
- package/compiler/semantic-model.go +336 -91
- package/compiler/semantic-model_test.go +50 -1
- package/compiler/service.go +9 -3
- package/compiler/skeleton_test.go +1921 -298
- package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
- package/compiler/tsworkspace/owner.go +8 -0
- package/compiler/tsworkspace/tool-process-other.go +14 -0
- package/compiler/tsworkspace/tool-process-unix.go +19 -0
- package/compiler/typescript-emitter.go +122 -9
- package/dist/gs/builtin/builtin.d.ts +20 -1
- package/dist/gs/builtin/builtin.js +246 -26
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +24 -10
- package/dist/gs/builtin/channel.js +107 -25
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/defer.d.ts +1 -0
- package/dist/gs/builtin/defer.js +12 -2
- package/dist/gs/builtin/defer.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +9 -0
- package/dist/gs/builtin/hostio.js +25 -0
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/map.js +40 -6
- package/dist/gs/builtin/map.js.map +1 -1
- package/dist/gs/builtin/print.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +43 -9
- package/dist/gs/builtin/slice.js +437 -234
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +2 -0
- package/dist/gs/builtin/type.js +47 -7
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +2 -0
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +28 -28
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/iter.gs.js +13 -13
- package/dist/gs/bytes/iter.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +26 -0
- package/dist/gs/compress/zlib/index.js +168 -0
- package/dist/gs/compress/zlib/index.js.map +1 -0
- package/dist/gs/context/context.d.ts +1 -1
- package/dist/gs/context/context.js +8 -3
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/ecdh/index.d.ts +52 -0
- package/dist/gs/crypto/ecdh/index.js +226 -0
- package/dist/gs/crypto/ecdh/index.js.map +1 -0
- package/dist/gs/crypto/ed25519/index.d.ts +34 -0
- package/dist/gs/crypto/ed25519/index.js +160 -0
- package/dist/gs/crypto/ed25519/index.js.map +1 -0
- package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
- package/dist/gs/crypto/internal/constanttime/index.js +18 -0
- package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
- package/dist/gs/crypto/rand/index.d.ts +2 -0
- package/dist/gs/crypto/rand/index.js +85 -0
- package/dist/gs/crypto/rand/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.d.ts +8 -0
- package/dist/gs/crypto/sha256/index.js +118 -0
- package/dist/gs/crypto/sha256/index.js.map +1 -0
- package/dist/gs/crypto/sha512/index.d.ts +14 -0
- package/dist/gs/crypto/sha512/index.js +129 -0
- package/dist/gs/crypto/sha512/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +3 -0
- package/dist/gs/encoding/json/index.js +15 -0
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.js +29 -6
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +7 -7
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +52 -18
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +56 -20
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +57 -3
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +366 -1
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js +3 -2
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -1
- package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
- package/dist/gs/go/token/index.js +11 -4
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/fnv/index.d.ts +57 -0
- package/dist/gs/hash/fnv/index.js +299 -0
- package/dist/gs/hash/fnv/index.js.map +1 -0
- package/dist/gs/hash/index.d.ts +17 -0
- package/dist/gs/hash/index.js +94 -0
- package/dist/gs/hash/index.js.map +1 -0
- package/dist/gs/io/fs/readlink.js +2 -6
- package/dist/gs/io/fs/readlink.js.map +1 -1
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/iter/iter.d.ts +3 -2
- package/dist/gs/iter/iter.js.map +1 -1
- package/dist/gs/maps/iter.d.ts +5 -5
- package/dist/gs/maps/iter.js +48 -21
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.d.ts +6 -6
- package/dist/gs/math/bits/index.js +14 -24
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.js +3 -1
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +20 -1
- package/dist/gs/net/http/httptest/index.js +83 -3
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +110 -6
- package/dist/gs/net/http/index.js +262 -16
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/net/http/pprof/index.d.ts +8 -0
- package/dist/gs/net/http/pprof/index.js +59 -0
- package/dist/gs/net/http/pprof/index.js.map +1 -0
- package/dist/gs/os/error.gs.js +9 -7
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +95 -15
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.d.ts +5 -3
- package/dist/gs/path/filepath/path.js +65 -10
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +3 -2
- package/dist/gs/reflect/index.js +2 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/iter.js +2 -2
- package/dist/gs/reflect/iter.js.map +1 -1
- package/dist/gs/reflect/map.js +26 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +24 -5
- package/dist/gs/reflect/type.js +390 -38
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +1 -0
- package/dist/gs/reflect/types.js +3 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +4 -1
- package/dist/gs/reflect/value.js +39 -1
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +1 -1
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/debug/index.d.ts +39 -0
- package/dist/gs/runtime/debug/index.js +58 -0
- package/dist/gs/runtime/debug/index.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +20 -0
- package/dist/gs/runtime/pprof/index.js +85 -0
- package/dist/gs/runtime/pprof/index.js.map +1 -0
- package/dist/gs/runtime/trace/index.d.ts +19 -0
- package/dist/gs/runtime/trace/index.js +64 -0
- package/dist/gs/runtime/trace/index.js.map +1 -0
- package/dist/gs/slices/slices.d.ts +24 -9
- package/dist/gs/slices/slices.js +229 -24
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/slice.gs.d.ts +5 -3
- package/dist/gs/sort/slice.gs.js +55 -17
- package/dist/gs/sort/slice.gs.js.map +1 -1
- package/dist/gs/strings/builder.js +26 -17
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/strings/iter.js +140 -75
- package/dist/gs/strings/iter.js.map +1 -1
- package/dist/gs/strings/replace.js +2 -2
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.js +52 -6
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +6 -3
- package/dist/gs/sync/sync.js +39 -11
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/errors.d.ts +116 -112
- package/dist/gs/syscall/errors.js +38 -1
- package/dist/gs/syscall/errors.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +2 -8
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/syscall/js/index.js +20 -12
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/syscall/types.d.ts +4 -1
- package/dist/gs/syscall/types.js.map +1 -1
- package/dist/gs/testing/testing.d.ts +4 -3
- package/dist/gs/testing/testing.js +21 -4
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.js +22 -0
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/dist/gs/unique/index.js +7 -2
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +8 -8
- package/go.sum +14 -23
- package/gs/builtin/builtin.ts +364 -37
- package/gs/builtin/channel.ts +161 -29
- package/gs/builtin/defer.ts +13 -2
- package/gs/builtin/hostio.test.ts +1 -0
- package/gs/builtin/hostio.ts +38 -0
- package/gs/builtin/map.ts +46 -6
- package/gs/builtin/print.ts +12 -3
- package/gs/builtin/runtime-contract.test.ts +257 -10
- package/gs/builtin/slice.test.ts +70 -0
- package/gs/builtin/slice.ts +566 -255
- package/gs/builtin/type.ts +53 -9
- package/gs/builtin/varRef.ts +2 -0
- package/gs/bytes/buffer.gs.ts +28 -28
- package/gs/bytes/iter.gs.ts +13 -14
- package/gs/compress/zlib/index.test.ts +28 -0
- package/gs/compress/zlib/index.ts +200 -0
- package/gs/compress/zlib/meta.json +3 -0
- package/gs/context/context.test.ts +31 -1
- package/gs/context/context.ts +9 -4
- package/gs/crypto/ecdh/index.test.ts +43 -0
- package/gs/crypto/ecdh/index.ts +274 -0
- package/gs/crypto/ed25519/index.test.ts +41 -0
- package/gs/crypto/ed25519/index.ts +238 -0
- package/gs/crypto/ed25519/meta.json +13 -0
- package/gs/crypto/internal/constanttime/index.test.ts +25 -0
- package/gs/crypto/internal/constanttime/index.ts +22 -0
- package/gs/crypto/rand/index.test.ts +89 -1
- package/gs/crypto/rand/index.ts +103 -1
- package/gs/crypto/rand/meta.json +4 -1
- package/gs/crypto/sha256/index.test.ts +78 -0
- package/gs/crypto/sha256/index.ts +150 -0
- package/gs/crypto/sha256/meta.json +9 -0
- package/gs/crypto/sha512/index.test.ts +31 -0
- package/gs/crypto/sha512/index.ts +161 -0
- package/gs/crypto/sha512/meta.json +11 -0
- package/gs/encoding/json/index.test.ts +25 -3
- package/gs/encoding/json/index.ts +21 -3
- package/gs/errors/errors.test.ts +4 -1
- package/gs/errors/errors.ts +32 -8
- package/gs/fmt/fmt.test.ts +3 -1
- package/gs/fmt/fmt.ts +1 -5
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +62 -7
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +78 -36
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +32 -11
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +122 -43
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +518 -4
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +6 -0
- package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
- package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
- package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
- package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
- package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
- package/gs/github.com/klauspost/compress/internal/le/index.test.ts +2 -1
- package/gs/github.com/klauspost/compress/internal/le/index.ts +6 -5
- package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
- package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
- package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
- package/gs/go/token/index.ts +17 -4
- package/gs/hash/fnv/index.test.ts +67 -0
- package/gs/hash/fnv/index.ts +351 -0
- package/gs/hash/fnv/meta.json +3 -0
- package/gs/hash/index.test.ts +37 -0
- package/gs/hash/index.ts +118 -0
- package/gs/hash/meta.json +5 -0
- package/gs/internal/byteorder/index.test.ts +6 -6
- package/gs/io/fs/readlink.ts +40 -48
- package/gs/io/fs/walk.ts +10 -2
- package/gs/io/io.ts +4 -1
- package/gs/iter/iter.ts +8 -2
- package/gs/maps/iter.ts +69 -26
- package/gs/maps/maps.test.ts +23 -0
- package/gs/maps/maps.ts +6 -6
- package/gs/math/bits/index.test.ts +20 -0
- package/gs/math/bits/index.ts +15 -28
- package/gs/mime/index.ts +8 -2
- package/gs/net/http/httptest/index.test.ts +53 -0
- package/gs/net/http/httptest/index.ts +98 -3
- package/gs/net/http/index.test.ts +129 -1
- package/gs/net/http/index.ts +370 -19
- package/gs/net/http/meta.json +6 -0
- package/gs/net/http/pprof/index.test.ts +47 -0
- package/gs/net/http/pprof/index.ts +65 -0
- package/gs/os/error.gs.ts +9 -10
- package/gs/os/error.test.ts +41 -0
- package/gs/os/file_unix_js.test.ts +55 -0
- package/gs/os/tempfile.gs.test.ts +37 -10
- package/gs/os/types_js.gs.ts +94 -15
- package/gs/path/filepath/match.ts +4 -1
- package/gs/path/filepath/meta.json +6 -0
- package/gs/path/filepath/path.test.ts +57 -2
- package/gs/path/filepath/path.ts +91 -12
- package/gs/reflect/field.test.ts +63 -0
- package/gs/reflect/index.ts +4 -1
- package/gs/reflect/iter.ts +2 -2
- package/gs/reflect/map.test.ts +24 -2
- package/gs/reflect/map.ts +35 -0
- package/gs/reflect/type.ts +543 -60
- package/gs/reflect/typefor.test.ts +100 -0
- package/gs/reflect/types.ts +3 -1
- package/gs/reflect/value.ts +50 -1
- package/gs/reflect/visiblefields.ts +1 -1
- package/gs/runtime/debug/index.test.ts +22 -1
- package/gs/runtime/debug/index.ts +88 -0
- package/gs/runtime/pprof/index.test.ts +36 -0
- package/gs/runtime/pprof/index.ts +104 -0
- package/gs/runtime/pprof/meta.json +6 -0
- package/gs/runtime/trace/index.test.ts +45 -0
- package/gs/runtime/trace/index.ts +97 -0
- package/gs/runtime/trace/meta.json +7 -0
- package/gs/slices/meta.json +2 -1
- package/gs/slices/slices.test.ts +86 -0
- package/gs/slices/slices.ts +284 -37
- package/gs/sort/slice.gs.ts +73 -23
- package/gs/sort/slice.test.ts +40 -0
- package/gs/strings/builder.test.ts +8 -0
- package/gs/strings/builder.ts +29 -17
- package/gs/strings/iter.test.ts +5 -7
- package/gs/strings/iter.ts +146 -71
- package/gs/strings/replace.test.ts +1 -4
- package/gs/strings/replace.ts +6 -6
- package/gs/strings/strings.test.ts +4 -0
- package/gs/strings/strings.ts +54 -6
- package/gs/sync/sync.test.ts +57 -1
- package/gs/sync/sync.ts +45 -13
- package/gs/syscall/errors.ts +158 -115
- package/gs/syscall/fs.ts +8 -8
- package/gs/syscall/js/index.ts +49 -22
- package/gs/syscall/net.test.ts +26 -0
- package/gs/syscall/types.ts +7 -2
- package/gs/testing/testing.test.ts +56 -0
- package/gs/testing/testing.ts +27 -10
- package/gs/time/meta.json +2 -2
- package/gs/time/time.test.ts +4 -0
- package/gs/time/time.ts +33 -2
- package/gs/unicode/unicode.test.ts +14 -3
- package/gs/unicode/unicode.ts +1 -5
- package/gs/unique/index.ts +9 -2
- package/package.json +3 -3
|
@@ -7,7 +7,9 @@ import (
|
|
|
7
7
|
"io"
|
|
8
8
|
"io/fs"
|
|
9
9
|
"maps"
|
|
10
|
+
"os"
|
|
10
11
|
"path"
|
|
12
|
+
"path/filepath"
|
|
11
13
|
"slices"
|
|
12
14
|
"strings"
|
|
13
15
|
|
|
@@ -26,6 +28,12 @@ type overridePackageFacts struct {
|
|
|
26
28
|
dependencies []string
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
type overridePackageRoot struct {
|
|
32
|
+
pkgPath string
|
|
33
|
+
fsys fs.FS
|
|
34
|
+
dir string
|
|
35
|
+
}
|
|
36
|
+
|
|
29
37
|
// HasPackage returns true when pkgPath has a GoScript override package.
|
|
30
38
|
func (f *OverrideFacts) HasPackage(pkgPath string) bool {
|
|
31
39
|
if f == nil || pkgPath == "" {
|
|
@@ -93,10 +101,10 @@ func (f *OverrideFacts) importPackageRoot(importPath string) (string, bool) {
|
|
|
93
101
|
return "", false
|
|
94
102
|
}
|
|
95
103
|
|
|
96
|
-
func buildOverrideFacts(ctx context.Context) (*OverrideFacts, []Diagnostic) {
|
|
97
|
-
roots,
|
|
98
|
-
if
|
|
99
|
-
return nil,
|
|
104
|
+
func buildOverrideFacts(ctx context.Context, overrideDirs []string) (*OverrideFacts, []Diagnostic) {
|
|
105
|
+
roots, diagnostics := discoverOverridePackageRoots(overrideDirs)
|
|
106
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
107
|
+
return nil, diagnostics
|
|
100
108
|
}
|
|
101
109
|
paths := make([]string, 0, len(roots))
|
|
102
110
|
for pkgPath := range roots {
|
|
@@ -105,17 +113,16 @@ func buildOverrideFacts(ctx context.Context) (*OverrideFacts, []Diagnostic) {
|
|
|
105
113
|
slices.Sort(paths)
|
|
106
114
|
|
|
107
115
|
facts := &OverrideFacts{packages: make(map[string]overridePackageFacts, len(paths))}
|
|
108
|
-
var diagnostics []Diagnostic
|
|
109
116
|
for _, pkgPath := range paths {
|
|
110
117
|
if err := ctx.Err(); err != nil {
|
|
111
118
|
return facts, []Diagnostic{contextCanceledDiagnostic(err)}
|
|
112
119
|
}
|
|
113
|
-
metadata, err := loadOverrideMetadata(pkgPath)
|
|
120
|
+
metadata, err := loadOverrideMetadata(roots[pkgPath])
|
|
114
121
|
if err != nil {
|
|
115
122
|
diagnostics = append(diagnostics, overrideError("read override metadata", pkgPath, err))
|
|
116
123
|
continue
|
|
117
124
|
}
|
|
118
|
-
copyPackage, dependencies, packageDiagnostics := loadOverrideCopyPackage(pkgPath, roots, metadata)
|
|
125
|
+
copyPackage, dependencies, packageDiagnostics := loadOverrideCopyPackage(roots[pkgPath], roots, metadata)
|
|
119
126
|
diagnostics = append(diagnostics, packageDiagnostics...)
|
|
120
127
|
if diagnosticsHaveErrors(packageDiagnostics) {
|
|
121
128
|
continue
|
|
@@ -132,29 +139,62 @@ func buildOverrideFacts(ctx context.Context) (*OverrideFacts, []Diagnostic) {
|
|
|
132
139
|
return facts, diagnostics
|
|
133
140
|
}
|
|
134
141
|
|
|
135
|
-
func discoverOverridePackageRoots() (map[string]
|
|
136
|
-
roots := make(map[string]
|
|
137
|
-
|
|
142
|
+
func discoverOverridePackageRoots(overrideDirs []string) (map[string]overridePackageRoot, []Diagnostic) {
|
|
143
|
+
roots := make(map[string]overridePackageRoot)
|
|
144
|
+
var diagnostics []Diagnostic
|
|
145
|
+
for _, dir := range overrideDirs {
|
|
146
|
+
dir = strings.TrimSpace(dir)
|
|
147
|
+
if dir == "" {
|
|
148
|
+
continue
|
|
149
|
+
}
|
|
150
|
+
abs, err := filepath.Abs(dir)
|
|
151
|
+
if err != nil {
|
|
152
|
+
diagnostics = append(diagnostics, overrideError("resolve override directory", dir, err))
|
|
153
|
+
continue
|
|
154
|
+
}
|
|
155
|
+
if err := discoverOverridePackageRootsInFS(roots, os.DirFS(abs), ".", false); err != nil {
|
|
156
|
+
diagnostics = append(diagnostics, overrideError("discover override packages", abs, err))
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if err := discoverOverridePackageRootsInFS(roots, gs.GsOverrides, "gs", true); err != nil {
|
|
160
|
+
diagnostics = append(diagnostics, overrideError("discover override packages", "embedded gs", err))
|
|
161
|
+
}
|
|
162
|
+
return roots, diagnostics
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
func discoverOverridePackageRootsInFS(
|
|
166
|
+
roots map[string]overridePackageRoot,
|
|
167
|
+
fsys fs.FS,
|
|
168
|
+
rootDir string,
|
|
169
|
+
embedded bool,
|
|
170
|
+
) error {
|
|
171
|
+
return fs.WalkDir(fsys, rootDir, func(filePath string, entry fs.DirEntry, err error) error {
|
|
138
172
|
if err != nil {
|
|
139
173
|
return err
|
|
140
174
|
}
|
|
141
175
|
if entry.IsDir() || path.Base(filePath) != "index.ts" {
|
|
142
176
|
return nil
|
|
143
177
|
}
|
|
144
|
-
pkgPath := strings.TrimPrefix(path.Dir(filePath), "
|
|
178
|
+
pkgPath := strings.TrimPrefix(path.Dir(filePath), rootDir+"/")
|
|
179
|
+
if rootDir == "." {
|
|
180
|
+
pkgPath = path.Dir(filePath)
|
|
181
|
+
}
|
|
145
182
|
if pkgPath != "." && pkgPath != "" {
|
|
146
|
-
roots[pkgPath]
|
|
183
|
+
if _, exists := roots[pkgPath]; !exists || !embedded {
|
|
184
|
+
roots[pkgPath] = overridePackageRoot{
|
|
185
|
+
pkgPath: pkgPath,
|
|
186
|
+
fsys: fsys,
|
|
187
|
+
dir: path.Dir(filePath),
|
|
188
|
+
}
|
|
189
|
+
}
|
|
147
190
|
}
|
|
148
191
|
return nil
|
|
149
|
-
})
|
|
150
|
-
return nil, err
|
|
151
|
-
}
|
|
152
|
-
return roots, nil
|
|
192
|
+
})
|
|
153
193
|
}
|
|
154
194
|
|
|
155
|
-
func loadOverrideMetadata(
|
|
195
|
+
func loadOverrideMetadata(root overridePackageRoot) (OverrideMetadata, error) {
|
|
156
196
|
metadata := newOverrideMetadata()
|
|
157
|
-
data, err :=
|
|
197
|
+
data, err := fs.ReadFile(root.fsys, path.Join(root.dir, "meta.json"))
|
|
158
198
|
if err != nil {
|
|
159
199
|
if errors.Is(err, fs.ErrNotExist) {
|
|
160
200
|
return metadata, nil
|
|
@@ -188,11 +228,12 @@ func loadOverrideMetadata(pkgPath string) (OverrideMetadata, error) {
|
|
|
188
228
|
}
|
|
189
229
|
|
|
190
230
|
func loadOverrideCopyPackage(
|
|
191
|
-
|
|
192
|
-
roots map[string]
|
|
231
|
+
root overridePackageRoot,
|
|
232
|
+
roots map[string]overridePackageRoot,
|
|
193
233
|
metadata OverrideMetadata,
|
|
194
234
|
) (overrideCopyPackage, []string, []Diagnostic) {
|
|
195
|
-
|
|
235
|
+
pkgPath := root.pkgPath
|
|
236
|
+
if _, ok := roots[pkgPath]; !ok {
|
|
196
237
|
return overrideCopyPackage{}, nil, []Diagnostic{{
|
|
197
238
|
Severity: DiagnosticSeverityError,
|
|
198
239
|
Code: "goscript/overrides:missing-package",
|
|
@@ -215,14 +256,18 @@ func loadOverrideCopyPackage(
|
|
|
215
256
|
}
|
|
216
257
|
}
|
|
217
258
|
|
|
218
|
-
|
|
219
|
-
err := fs.WalkDir(gs.GsOverrides, root, func(filePath string, entry fs.DirEntry, walkErr error) error {
|
|
259
|
+
err := fs.WalkDir(root.fsys, root.dir, func(filePath string, entry fs.DirEntry, walkErr error) error {
|
|
220
260
|
if walkErr != nil {
|
|
221
261
|
return walkErr
|
|
222
262
|
}
|
|
223
263
|
if entry.IsDir() {
|
|
224
|
-
nestedPkg := strings.TrimPrefix(filePath, "
|
|
225
|
-
if
|
|
264
|
+
nestedPkg := strings.TrimPrefix(filePath, root.dir+"/")
|
|
265
|
+
if root.dir == "." {
|
|
266
|
+
nestedPkg = filePath
|
|
267
|
+
} else if nestedPkg != filePath {
|
|
268
|
+
nestedPkg = path.Join(pkgPath, nestedPkg)
|
|
269
|
+
}
|
|
270
|
+
if _, ok := roots[nestedPkg]; nestedPkg != pkgPath && ok {
|
|
226
271
|
return fs.SkipDir
|
|
227
272
|
}
|
|
228
273
|
return nil
|
|
@@ -230,11 +275,16 @@ func loadOverrideCopyPackage(
|
|
|
230
275
|
if !isOverrideSourceFile(filePath) {
|
|
231
276
|
return nil
|
|
232
277
|
}
|
|
233
|
-
data, readErr :=
|
|
278
|
+
data, readErr := fs.ReadFile(root.fsys, filePath)
|
|
234
279
|
if readErr != nil {
|
|
235
280
|
return readErr
|
|
236
281
|
}
|
|
237
|
-
rel := strings.TrimPrefix(filePath, "
|
|
282
|
+
rel := strings.TrimPrefix(filePath, root.dir+"/")
|
|
283
|
+
if root.dir == "." {
|
|
284
|
+
rel = filePath
|
|
285
|
+
} else if rel != filePath {
|
|
286
|
+
rel = path.Join(pkgPath, rel)
|
|
287
|
+
}
|
|
238
288
|
copyPackage.files = append(copyPackage.files, overrideCopyFile{
|
|
239
289
|
path: rel,
|
|
240
290
|
data: data,
|
|
@@ -20,12 +20,13 @@ type OverrideMetadata struct {
|
|
|
20
20
|
|
|
21
21
|
// OverrideRegistryOwner owns GoScript override package metadata and copy plans.
|
|
22
22
|
type OverrideRegistryOwner struct {
|
|
23
|
-
|
|
23
|
+
overrideDirs []string
|
|
24
|
+
facts *OverrideFacts
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
// NewOverrideRegistryOwner creates the override registry owner.
|
|
27
|
-
func NewOverrideRegistryOwner() *OverrideRegistryOwner {
|
|
28
|
-
return &OverrideRegistryOwner{}
|
|
28
|
+
func NewOverrideRegistryOwner(overrideDirs ...string) *OverrideRegistryOwner {
|
|
29
|
+
return &OverrideRegistryOwner{overrideDirs: slices.Clone(overrideDirs)}
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
// Facts returns the immutable compiler-visible override facts.
|
|
@@ -36,7 +37,7 @@ func (o *OverrideRegistryOwner) Facts(ctx context.Context) (*OverrideFacts, []Di
|
|
|
36
37
|
if o.facts != nil {
|
|
37
38
|
return o.facts, nil
|
|
38
39
|
}
|
|
39
|
-
facts, diagnostics := buildOverrideFacts(ctx)
|
|
40
|
+
facts, diagnostics := buildOverrideFacts(ctx, o.overrideDirs)
|
|
40
41
|
if diagnosticsHaveErrors(diagnostics) {
|
|
41
42
|
return facts, diagnostics
|
|
42
43
|
}
|
|
@@ -118,6 +118,47 @@ func TestOverrideRegistryCopiesRuntimeAndOverrides(t *testing.T) {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
func TestOverrideRegistryCopiesExternalOverride(t *testing.T) {
|
|
122
|
+
overrideDir := filepath.Join(t.TempDir(), "gs")
|
|
123
|
+
writeFixtureFile(t, overrideDir, "example.test/lib/index.ts", strings.Join([]string{
|
|
124
|
+
"import * as helper from '@goscript/example.test/helper/index.js'",
|
|
125
|
+
"export function Run(): void { helper.Run() }",
|
|
126
|
+
"",
|
|
127
|
+
}, "\n"))
|
|
128
|
+
writeFixtureFile(t, overrideDir, "example.test/lib/meta.json", `{"dependencies":["example.test/helper"]}`)
|
|
129
|
+
writeFixtureFile(t, overrideDir, "example.test/helper/index.ts", "export function Run(): void {}\n")
|
|
130
|
+
|
|
131
|
+
owner := NewOverrideRegistryOwner(overrideDir)
|
|
132
|
+
req := &CompileRequest{
|
|
133
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
134
|
+
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
135
|
+
}
|
|
136
|
+
plan, diagnostics := owner.CopyPlan(context.Background(), req, &PackageGraph{Nodes: []*PackageGraphNode{{
|
|
137
|
+
PkgPath: "example.test/lib",
|
|
138
|
+
OverrideCandidate: true,
|
|
139
|
+
}}})
|
|
140
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
141
|
+
t.Fatalf("copy plan failed: %#v", diagnostics)
|
|
142
|
+
}
|
|
143
|
+
copied, diagnostics := owner.CopyPackages(context.Background(), req, plan)
|
|
144
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
145
|
+
t.Fatalf("copy failed: %#v", diagnostics)
|
|
146
|
+
}
|
|
147
|
+
for _, pkg := range []string{"builtin", "example.test/helper", "example.test/lib"} {
|
|
148
|
+
if !slices.Contains(copied, pkg) {
|
|
149
|
+
t.Fatalf("missing copied package %s in %v", pkg, copied)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
for _, path := range []string{
|
|
153
|
+
"@goscript/example.test/helper/index.ts",
|
|
154
|
+
"@goscript/example.test/lib/index.ts",
|
|
155
|
+
} {
|
|
156
|
+
if _, err := os.Stat(filepath.Join(req.OutputPath, filepath.FromSlash(path))); err != nil {
|
|
157
|
+
t.Fatalf("expected copied file %s: %v", path, err)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
121
162
|
func TestOverrideRegistryReportsMissingOverridePackage(t *testing.T) {
|
|
122
163
|
_, diagnostics := NewOverrideRegistryOwner().CopyPlan(context.Background(), &CompileRequest{
|
|
123
164
|
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
@@ -252,3 +293,97 @@ func TestCompilePackagesAwaitsOverrideAsyncMethods(t *testing.T) {
|
|
|
252
293
|
t.Fatalf("override async method call was not awaited:\n%s", string(content))
|
|
253
294
|
}
|
|
254
295
|
}
|
|
296
|
+
|
|
297
|
+
func TestCompilePackagesPropagatesOverrideAsyncInterfaceMethods(t *testing.T) {
|
|
298
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
299
|
+
"go.mod": "module example.test/overrideasynciface\n\ngo 1.25.3\n",
|
|
300
|
+
"main.go": strings.Join([]string{
|
|
301
|
+
"package main",
|
|
302
|
+
"import \"net/http\"",
|
|
303
|
+
"type client struct { rt http.RoundTripper }",
|
|
304
|
+
"func (c *client) Do(req *http.Request) (*http.Response, error) {",
|
|
305
|
+
" return c.rt.RoundTrip(req)",
|
|
306
|
+
"}",
|
|
307
|
+
"func Use(c *client, req *http.Request) (*http.Response, error) {",
|
|
308
|
+
" return c.Do(req)",
|
|
309
|
+
"}",
|
|
310
|
+
"func main() {}",
|
|
311
|
+
"",
|
|
312
|
+
}, "\n"),
|
|
313
|
+
})
|
|
314
|
+
out := filepath.Join(t.TempDir(), "out")
|
|
315
|
+
comp, err := NewCompiler(&Config{
|
|
316
|
+
Dir: moduleDir,
|
|
317
|
+
OutputPath: out,
|
|
318
|
+
AllDependencies: true,
|
|
319
|
+
}, nil, nil)
|
|
320
|
+
if err != nil {
|
|
321
|
+
t.Fatal(err.Error())
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
|
|
325
|
+
t.Fatal(err.Error())
|
|
326
|
+
}
|
|
327
|
+
content, err := os.ReadFile(filepath.Join(out, "@goscript", "example.test", "overrideasynciface", "main.gs.ts"))
|
|
328
|
+
if err != nil {
|
|
329
|
+
t.Fatal(err.Error())
|
|
330
|
+
}
|
|
331
|
+
text := string(content)
|
|
332
|
+
for _, want := range []string{
|
|
333
|
+
"public async Do(req: http.Request | $.VarRef<http.Request> | null): globalThis.Promise<[http.Response | $.VarRef<http.Response> | null, $.GoError]>",
|
|
334
|
+
"return await $.pointerValue<Exclude<http.RoundTripper, null>>($.pointerValue<client>(c).rt).RoundTrip(req)",
|
|
335
|
+
"export async function Use(c: client | $.VarRef<client> | null, req: http.Request | $.VarRef<http.Request> | null): globalThis.Promise<[http.Response | $.VarRef<http.Response> | null, $.GoError]>",
|
|
336
|
+
"return await client.prototype.Do.call(c, req)",
|
|
337
|
+
} {
|
|
338
|
+
if !strings.Contains(text, want) {
|
|
339
|
+
t.Fatalf("missing %q in generated output:\n%s", want, text)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
func TestCompilePackagesAwaitsOverrideAsyncFunctions(t *testing.T) {
|
|
345
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
346
|
+
"go.mod": "module example.test/overrideasyncfunc\n\ngo 1.25.3\n",
|
|
347
|
+
"main.go": strings.Join([]string{
|
|
348
|
+
"package main",
|
|
349
|
+
"import (",
|
|
350
|
+
" \"io/fs\"",
|
|
351
|
+
" \"path/filepath\"",
|
|
352
|
+
" \"sync\"",
|
|
353
|
+
")",
|
|
354
|
+
"func main() {",
|
|
355
|
+
" var m sync.Map",
|
|
356
|
+
" _ = filepath.WalkDir(\".\", func(path string, d fs.DirEntry, err error) error {",
|
|
357
|
+
" if _, ok := m.Load(path); ok {",
|
|
358
|
+
" return nil",
|
|
359
|
+
" }",
|
|
360
|
+
" return nil",
|
|
361
|
+
" })",
|
|
362
|
+
"}",
|
|
363
|
+
"",
|
|
364
|
+
}, "\n"),
|
|
365
|
+
})
|
|
366
|
+
out := filepath.Join(t.TempDir(), "out")
|
|
367
|
+
comp, err := NewCompiler(&Config{
|
|
368
|
+
Dir: moduleDir,
|
|
369
|
+
OutputPath: out,
|
|
370
|
+
AllDependencies: true,
|
|
371
|
+
}, nil, nil)
|
|
372
|
+
if err != nil {
|
|
373
|
+
t.Fatal(err.Error())
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
|
|
377
|
+
t.Fatal(err.Error())
|
|
378
|
+
}
|
|
379
|
+
content, err := os.ReadFile(filepath.Join(out, "@goscript", "example.test", "overrideasyncfunc", "main.gs.ts"))
|
|
380
|
+
if err != nil {
|
|
381
|
+
t.Fatal(err.Error())
|
|
382
|
+
}
|
|
383
|
+
if !strings.Contains(string(content), "await filepath.WalkDir") {
|
|
384
|
+
t.Fatalf("override async function call was not awaited:\n%s", string(content))
|
|
385
|
+
}
|
|
386
|
+
if !strings.Contains(string(content), "$.functionValue(async") {
|
|
387
|
+
t.Fatalf("walk callback was not lowered as async:\n%s", string(content))
|
|
388
|
+
}
|
|
389
|
+
}
|
|
@@ -258,6 +258,55 @@ func TestPackageGraphDetectsOverrideCandidates(t *testing.T) {
|
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
func TestPackageGraphDetectsExternalOverrideCandidates(t *testing.T) {
|
|
262
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
263
|
+
"go.mod": strings.Join([]string{
|
|
264
|
+
"module example.test/externaloverride",
|
|
265
|
+
"",
|
|
266
|
+
"go 1.25.3",
|
|
267
|
+
"",
|
|
268
|
+
"require example.test/lib v0.0.0",
|
|
269
|
+
"replace example.test/lib => ./lib",
|
|
270
|
+
"",
|
|
271
|
+
}, "\n"),
|
|
272
|
+
"main.go": "package main\nimport \"example.test/lib\"\nfunc main() { lib.Run() }\n",
|
|
273
|
+
"lib/go.mod": strings.Join([]string{
|
|
274
|
+
"module example.test/lib",
|
|
275
|
+
"",
|
|
276
|
+
"go 1.25.3",
|
|
277
|
+
"",
|
|
278
|
+
"require example.test/heavy v0.0.0",
|
|
279
|
+
"replace example.test/heavy => ../heavy",
|
|
280
|
+
"",
|
|
281
|
+
}, "\n"),
|
|
282
|
+
"lib/lib.go": "package lib\nimport \"example.test/heavy\"\nfunc Run() { heavy.Run() }\n",
|
|
283
|
+
"heavy/go.mod": "module example.test/heavy\n\ngo 1.25.3\n",
|
|
284
|
+
"heavy/heavy.go": "package heavy\nfunc Run() {}\n",
|
|
285
|
+
})
|
|
286
|
+
overrideDir := filepath.Join(t.TempDir(), "gs")
|
|
287
|
+
writeFixtureFile(t, overrideDir, "example.test/lib/index.ts", "export function Run(): void {}\n")
|
|
288
|
+
|
|
289
|
+
overrideOwner := NewOverrideRegistryOwner(overrideDir)
|
|
290
|
+
req := &CompileRequest{
|
|
291
|
+
Patterns: []string{"."},
|
|
292
|
+
Dir: moduleDir,
|
|
293
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
294
|
+
DependencyMode: DependencyModeAll,
|
|
295
|
+
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
296
|
+
}
|
|
297
|
+
graph, diagnostics := NewPackageGraphOwner(overrideOwner).Load(context.Background(), req)
|
|
298
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
299
|
+
t.Fatalf("package graph failed: %#v", diagnostics)
|
|
300
|
+
}
|
|
301
|
+
lib := graph.NodesByPackagePath["example.test/lib"]
|
|
302
|
+
if lib == nil || !lib.OverrideCandidate {
|
|
303
|
+
t.Fatalf("expected external override candidate for lib")
|
|
304
|
+
}
|
|
305
|
+
if graph.NodesByPackagePath["example.test/heavy"] != nil {
|
|
306
|
+
t.Fatalf("external override dependency should not be collected")
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
261
310
|
func TestPackageGraphOverrideCandidatesRequirePackageIndex(t *testing.T) {
|
|
262
311
|
parent := "github.com/aperturerobotics/wasivm/wazero/kernel"
|
|
263
312
|
child := parent + "/runtime"
|
|
@@ -293,17 +342,23 @@ func writePackageGraphFixture(t *testing.T, files map[string]string) string {
|
|
|
293
342
|
|
|
294
343
|
dir := t.TempDir()
|
|
295
344
|
for name, contents := range files {
|
|
296
|
-
|
|
297
|
-
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
298
|
-
t.Fatal(err.Error())
|
|
299
|
-
}
|
|
300
|
-
if err := os.WriteFile(path, []byte(contents), 0o644); err != nil {
|
|
301
|
-
t.Fatal(err.Error())
|
|
302
|
-
}
|
|
345
|
+
writeFixtureFile(t, dir, name, contents)
|
|
303
346
|
}
|
|
304
347
|
return dir
|
|
305
348
|
}
|
|
306
349
|
|
|
350
|
+
func writeFixtureFile(t *testing.T, root, name, contents string) {
|
|
351
|
+
t.Helper()
|
|
352
|
+
|
|
353
|
+
path := filepath.Join(root, filepath.FromSlash(name))
|
|
354
|
+
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
355
|
+
t.Fatal(err.Error())
|
|
356
|
+
}
|
|
357
|
+
if err := os.WriteFile(path, []byte(contents), 0o644); err != nil {
|
|
358
|
+
t.Fatal(err.Error())
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
307
362
|
func requireDiagnosticCode(t *testing.T, diagnostics []Diagnostic, code string) {
|
|
308
363
|
t.Helper()
|
|
309
364
|
|
|
@@ -2,8 +2,8 @@ package compiler
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"go/ast"
|
|
5
|
-
"go/types"
|
|
6
5
|
"slices"
|
|
6
|
+
"strconv"
|
|
7
7
|
"strings"
|
|
8
8
|
"unicode"
|
|
9
9
|
|
|
@@ -57,13 +57,10 @@ func discoverPackageTestFunctions(pkg *packages.Package) []PackageTestFunction {
|
|
|
57
57
|
}
|
|
58
58
|
var tests []PackageTestFunction
|
|
59
59
|
for _, file := range pkg.Syntax {
|
|
60
|
+
testingAliases := fileTestingAliases(file)
|
|
60
61
|
for _, decl := range file.Decls {
|
|
61
|
-
fn,
|
|
62
|
-
if !
|
|
63
|
-
continue
|
|
64
|
-
}
|
|
65
|
-
obj, _ := pkg.TypesInfo.Defs[fn.Name].(*types.Func)
|
|
66
|
-
if !isOrdinaryTestFunc(obj) {
|
|
62
|
+
fn, _ := decl.(*ast.FuncDecl)
|
|
63
|
+
if !isOrdinaryTestFuncDecl(fn, testingAliases) {
|
|
67
64
|
continue
|
|
68
65
|
}
|
|
69
66
|
tests = append(tests, PackageTestFunction{
|
|
@@ -75,23 +72,50 @@ func discoverPackageTestFunctions(pkg *packages.Package) []PackageTestFunction {
|
|
|
75
72
|
return tests
|
|
76
73
|
}
|
|
77
74
|
|
|
78
|
-
func
|
|
79
|
-
if fn == nil {
|
|
75
|
+
func isOrdinaryTestFuncDecl(fn *ast.FuncDecl, testingAliases map[string]bool) bool {
|
|
76
|
+
if fn == nil || fn.Recv != nil || !isTestName(fn.Name.Name) || fn.Type == nil {
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
if fn.Type.Results != nil && len(fn.Type.Results.List) != 0 {
|
|
80
80
|
return false
|
|
81
81
|
}
|
|
82
|
-
|
|
83
|
-
if sig == nil || sig.Params().Len() != 1 || sig.Results().Len() != 0 {
|
|
82
|
+
if fn.Type.Params == nil || len(fn.Type.Params.List) != 1 {
|
|
84
83
|
return false
|
|
85
84
|
}
|
|
86
|
-
|
|
87
|
-
if
|
|
85
|
+
param := fn.Type.Params.List[0]
|
|
86
|
+
if len(param.Names) > 1 {
|
|
88
87
|
return false
|
|
89
88
|
}
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
ptr, ok := param.Type.(*ast.StarExpr)
|
|
90
|
+
return ok && isTestingT(ptr.X, testingAliases)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
func fileTestingAliases(file *ast.File) map[string]bool {
|
|
94
|
+
aliases := make(map[string]bool)
|
|
95
|
+
for _, imp := range file.Imports {
|
|
96
|
+
path, err := strconv.Unquote(imp.Path.Value)
|
|
97
|
+
if err != nil || path != "testing" {
|
|
98
|
+
continue
|
|
99
|
+
}
|
|
100
|
+
name := "testing"
|
|
101
|
+
if imp.Name != nil {
|
|
102
|
+
name = imp.Name.Name
|
|
103
|
+
}
|
|
104
|
+
aliases[name] = true
|
|
105
|
+
}
|
|
106
|
+
return aliases
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
func isTestingT(expr ast.Expr, aliases map[string]bool) bool {
|
|
110
|
+
switch typed := expr.(type) {
|
|
111
|
+
case *ast.SelectorExpr:
|
|
112
|
+
base, _ := typed.X.(*ast.Ident)
|
|
113
|
+
return base != nil && aliases[base.Name] && typed.Sel.Name == "T"
|
|
114
|
+
case *ast.Ident:
|
|
115
|
+
return aliases["."] && typed.Name == "T"
|
|
116
|
+
default:
|
|
92
117
|
return false
|
|
93
118
|
}
|
|
94
|
-
return named.Obj().Name() == "T" && named.Obj().Pkg().Path() == "testing"
|
|
95
119
|
}
|
|
96
120
|
|
|
97
121
|
func isTestName(name string) bool {
|
|
@@ -47,12 +47,7 @@ func (o *PackageGraphOwner) LoadTestGraph(ctx context.Context, req *CompileReque
|
|
|
47
47
|
packages.NeedFiles |
|
|
48
48
|
packages.NeedCompiledGoFiles |
|
|
49
49
|
packages.NeedImports |
|
|
50
|
-
packages.NeedDeps |
|
|
51
|
-
packages.NeedExportFile |
|
|
52
|
-
packages.NeedTypes |
|
|
53
50
|
packages.NeedSyntax |
|
|
54
|
-
packages.NeedTypesInfo |
|
|
55
|
-
packages.NeedTypesSizes |
|
|
56
51
|
packages.NeedForTest |
|
|
57
52
|
packages.NeedModule,
|
|
58
53
|
}
|
|
@@ -3,6 +3,7 @@ package compiler
|
|
|
3
3
|
import (
|
|
4
4
|
"context"
|
|
5
5
|
"path/filepath"
|
|
6
|
+
"slices"
|
|
6
7
|
"strings"
|
|
7
8
|
"testing"
|
|
8
9
|
)
|
|
@@ -21,9 +22,11 @@ func TestPackageGraphOwnerLoadTestGraphFacts(t *testing.T) {
|
|
|
21
22
|
"same/value_test.go": strings.Join([]string{
|
|
22
23
|
"package same",
|
|
23
24
|
"",
|
|
24
|
-
"import \"testing\"",
|
|
25
|
+
"import testpkg \"testing\"",
|
|
25
26
|
"",
|
|
26
|
-
"func TestAdd(t *
|
|
27
|
+
"func TestAdd(t *testpkg.T) {}",
|
|
28
|
+
"func TestIgnoredBadSignature(t *badT) {}",
|
|
29
|
+
"type badT struct{}",
|
|
27
30
|
"",
|
|
28
31
|
}, "\n"),
|
|
29
32
|
"external/value.go": strings.Join([]string{
|
|
@@ -69,6 +72,9 @@ func TestPackageGraphOwnerLoadTestGraphFacts(t *testing.T) {
|
|
|
69
72
|
if same == nil || same.SamePackageTests == nil || same.ExternalPackageTests != nil || !same.HasTests() {
|
|
70
73
|
t.Fatalf("unexpected same-package facts: %#v", same)
|
|
71
74
|
}
|
|
75
|
+
if len(same.SamePackageTests.Tests) != 1 || same.SamePackageTests.Tests[0].Name != "TestAdd" {
|
|
76
|
+
t.Fatalf("same-package test discovery should keep only ordinary tests: %#v", same.SamePackageTests.Tests)
|
|
77
|
+
}
|
|
72
78
|
external := graph.PackageByPath("example.test/testgraph/external")
|
|
73
79
|
if external == nil || external.ExternalPackageTests == nil || external.SamePackageTests != nil || !external.HasTests() {
|
|
74
80
|
t.Fatalf("unexpected external-package facts: %#v", external)
|
|
@@ -105,7 +111,7 @@ func TestPackageGraphOwnerLoadTestGraphScopesDiagnostics(t *testing.T) {
|
|
|
105
111
|
"import \"testing\"",
|
|
106
112
|
"",
|
|
107
113
|
"func TestBroken(t *testing.T) {",
|
|
108
|
-
"\
|
|
114
|
+
"\tif {",
|
|
109
115
|
"}",
|
|
110
116
|
"",
|
|
111
117
|
}, "\n"),
|
|
@@ -133,6 +139,58 @@ func TestPackageGraphOwnerLoadTestGraphScopesDiagnostics(t *testing.T) {
|
|
|
133
139
|
}
|
|
134
140
|
}
|
|
135
141
|
|
|
142
|
+
func TestPackageGraphOwnerLoadTestGraphDoesNotLoadDependencies(t *testing.T) {
|
|
143
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
144
|
+
"go.mod": "module example.test/testgraphdeps\n\ngo 1.25.3\n",
|
|
145
|
+
"clean/value.go": strings.Join([]string{
|
|
146
|
+
"package clean",
|
|
147
|
+
"",
|
|
148
|
+
"func Value() int {",
|
|
149
|
+
"\treturn 1",
|
|
150
|
+
"}",
|
|
151
|
+
"",
|
|
152
|
+
}, "\n"),
|
|
153
|
+
"clean/value_test.go": strings.Join([]string{
|
|
154
|
+
"package clean",
|
|
155
|
+
"",
|
|
156
|
+
"import (",
|
|
157
|
+
"\t\"testing\"",
|
|
158
|
+
"",
|
|
159
|
+
"\t\"example.test/testgraphdeps/brokendep\"",
|
|
160
|
+
")",
|
|
161
|
+
"",
|
|
162
|
+
"func TestValue(t *testing.T) {",
|
|
163
|
+
"\t_ = brokendep.Value",
|
|
164
|
+
"}",
|
|
165
|
+
"",
|
|
166
|
+
}, "\n"),
|
|
167
|
+
"brokendep/value.go": strings.Join([]string{
|
|
168
|
+
"package brokendep",
|
|
169
|
+
"",
|
|
170
|
+
"const Value =",
|
|
171
|
+
"",
|
|
172
|
+
}, "\n"),
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
graph, diagnostics := loadPackageTestGraph(t, &CompileRequest{
|
|
176
|
+
Patterns: []string{"./clean"},
|
|
177
|
+
Dir: moduleDir,
|
|
178
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
179
|
+
DependencyMode: DependencyModeRequested,
|
|
180
|
+
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
181
|
+
})
|
|
182
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
183
|
+
t.Fatalf("test graph discovery should not load dependency bodies: %#v", diagnostics)
|
|
184
|
+
}
|
|
185
|
+
clean := graph.PackageByPath("example.test/testgraphdeps/clean")
|
|
186
|
+
if clean == nil || clean.SamePackageTests == nil || len(clean.SamePackageTests.Tests) != 1 {
|
|
187
|
+
t.Fatalf("clean package test discovery failed: %#v", clean)
|
|
188
|
+
}
|
|
189
|
+
if !slices.Contains(clean.SamePackageTests.Imports, "example.test/testgraphdeps/brokendep") {
|
|
190
|
+
t.Fatalf("test graph should retain direct test imports: %#v", clean.SamePackageTests.Imports)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
136
194
|
func loadPackageTestGraph(t *testing.T, req *CompileRequest) (*PackageTestGraph, []Diagnostic) {
|
|
137
195
|
t.Helper()
|
|
138
196
|
|