goscript 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +267 -255
- package/cmd/goscript/cmd-test.go +193 -0
- package/cmd/goscript/cmd-test_test.go +76 -0
- package/cmd/goscript/main.go +1 -0
- package/compiler/build-flags.go +38 -0
- package/compiler/compile-request.go +2 -0
- package/compiler/compliance_test.go +0 -8
- package/compiler/gotest/owner.go +24 -0
- package/compiler/gotest/package-result.go +67 -0
- package/compiler/gotest/request.go +145 -0
- package/compiler/gotest/result.go +28 -0
- package/compiler/gotest/runner.go +588 -0
- package/compiler/gotest/runner_test.go +627 -0
- package/compiler/gotest/test.go +9 -0
- package/compiler/index.test.ts +1 -1
- package/compiler/lowered-program.go +71 -19
- package/compiler/lowering.go +5065 -569
- package/compiler/override-facts.go +307 -0
- package/compiler/override-registry.go +50 -189
- package/compiler/override-registry_test.go +47 -0
- package/compiler/package-graph.go +50 -27
- package/compiler/package-graph_test.go +37 -2
- package/compiler/package-test-function.go +9 -0
- package/compiler/package-test-graph-package.go +40 -0
- package/compiler/package-test-graph-variant.go +105 -0
- package/compiler/package-test-graph.go +117 -0
- package/compiler/package-test-graph_test.go +144 -0
- package/compiler/runtime-contract.go +189 -29
- package/compiler/runtime-contract_test.go +44 -30
- package/compiler/semantic-model-types.go +9 -6
- package/compiler/semantic-model.go +538 -38
- package/compiler/semantic-model_test.go +55 -0
- package/compiler/service.go +1 -1
- package/compiler/skeleton_test.go +679 -49
- package/compiler/tsworkspace/owner.go +334 -0
- package/compiler/tsworkspace/owner_test.go +93 -0
- package/compiler/tsworkspace/result.go +17 -0
- package/compiler/typescript-emitter.go +459 -82
- package/compiler/wasm/compile.go +1 -1
- package/compiler/wasm/compile_test.go +61 -11
- package/compiler/wasm_api.go +172 -7
- package/dist/gs/builtin/builtin.d.ts +20 -2
- package/dist/gs/builtin/builtin.js +194 -6
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +8 -0
- package/dist/gs/builtin/channel.js +12 -0
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +22 -2
- package/dist/gs/builtin/slice.js +216 -44
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +5 -2
- package/dist/gs/builtin/type.js +83 -24
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +5 -0
- package/dist/gs/builtin/varRef.js +23 -0
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +48 -44
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +20 -18
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/context/context.d.ts +5 -4
- package/dist/gs/context/context.js +10 -10
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
- package/dist/gs/embed/index.d.ts +7 -0
- package/dist/gs/embed/index.js +16 -0
- package/dist/gs/embed/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +1 -0
- package/dist/gs/encoding/json/index.js +18 -0
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.d.ts +4 -0
- package/dist/gs/errors/errors.js +81 -0
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +4 -4
- package/dist/gs/fmt/fmt.js +42 -11
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +35 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +211 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +825 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +163 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +449 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js +71 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
- package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
- package/dist/gs/go/internal/scannerhooks/index.js +5 -0
- package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
- package/dist/gs/go/scanner/index.d.ts +13 -0
- package/dist/gs/go/scanner/index.js +35 -0
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.d.ts +156 -0
- package/dist/gs/go/token/index.js +500 -4
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/internal/abi/index.d.ts +4 -0
- package/dist/gs/internal/abi/index.js +10 -0
- package/dist/gs/internal/abi/index.js.map +1 -1
- package/dist/gs/internal/bytealg/index.d.ts +2 -0
- package/dist/gs/internal/bytealg/index.js +14 -0
- package/dist/gs/internal/bytealg/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.d.ts +8 -2
- package/dist/gs/internal/byteorder/index.js +56 -25
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/godebug/index.d.ts +12 -0
- package/dist/gs/internal/godebug/index.js +30 -0
- package/dist/gs/internal/godebug/index.js.map +1 -0
- package/dist/gs/io/fs/index.d.ts +1 -0
- package/dist/gs/io/fs/index.js +1 -0
- package/dist/gs/io/fs/index.js.map +1 -1
- package/dist/gs/io/fs/readlink.d.ts +8 -0
- package/dist/gs/io/fs/readlink.js +64 -0
- package/dist/gs/io/fs/readlink.js.map +1 -0
- package/dist/gs/io/fs/walk.d.ts +3 -3
- package/dist/gs/io/fs/walk.js +7 -7
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.d.ts +40 -6
- package/dist/gs/io/io.js +151 -26
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/maps/iter.d.ts +3 -3
- package/dist/gs/maps/iter.js +3 -3
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.d.ts +2 -2
- package/dist/gs/maps/maps.js +1 -1
- package/dist/gs/maps/maps.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +13 -4
- package/dist/gs/math/bits/index.js +66 -34
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/math/const.gs.d.ts +5 -5
- package/dist/gs/math/const.gs.js +4 -4
- package/dist/gs/math/const.gs.js.map +1 -1
- package/dist/gs/mime/index.d.ts +1 -0
- package/dist/gs/mime/index.js +50 -0
- package/dist/gs/mime/index.js.map +1 -0
- package/dist/gs/net/http/httptest/index.d.ts +11 -0
- package/dist/gs/net/http/httptest/index.js +21 -0
- package/dist/gs/net/http/httptest/index.js.map +1 -0
- package/dist/gs/net/http/index.d.ts +27 -0
- package/dist/gs/net/http/index.js +61 -0
- package/dist/gs/net/http/index.js.map +1 -0
- package/dist/gs/os/dir_unix.gs.js +2 -2
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js +165 -3
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.d.ts +3 -1
- package/dist/gs/path/filepath/path.js +133 -4
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/path/path.d.ts +4 -1
- package/dist/gs/path/path.js +16 -4
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +1 -1
- package/dist/gs/reflect/index.js +1 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +3 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +7 -4
- package/dist/gs/reflect/type.js +148 -7
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/runtime/debug/index.d.ts +2 -0
- package/dist/gs/runtime/debug/index.js +8 -0
- package/dist/gs/runtime/debug/index.js.map +1 -0
- package/dist/gs/runtime/runtime.d.ts +35 -3
- package/dist/gs/runtime/runtime.js +72 -0
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +24 -5
- package/dist/gs/slices/slices.js +214 -5
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/slice.gs.d.ts +3 -3
- package/dist/gs/sort/slice.gs.js +6 -6
- package/dist/gs/sort/slice.gs.js.map +1 -1
- package/dist/gs/sort/sort.gs.d.ts +4 -4
- package/dist/gs/sort/sort.gs.js +11 -8
- package/dist/gs/sort/sort.gs.js.map +1 -1
- package/dist/gs/strings/builder.d.ts +1 -1
- package/dist/gs/strings/builder.js +3 -2
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
- package/dist/gs/sync/atomic/type.gs.js +0 -2
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -0
- package/dist/gs/sync/sync.js +27 -0
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/constants.d.ts +36 -24
- package/dist/gs/syscall/constants.js +12 -0
- package/dist/gs/syscall/constants.js.map +1 -1
- package/dist/gs/syscall/errors.d.ts +2 -0
- package/dist/gs/syscall/errors.js +8 -0
- package/dist/gs/syscall/errors.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +43 -0
- package/dist/gs/syscall/fs.js +102 -0
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/syscall/js/index.d.ts +90 -0
- package/dist/gs/syscall/js/index.js +375 -0
- package/dist/gs/syscall/js/index.js.map +1 -0
- package/dist/gs/syscall/types.d.ts +22 -0
- package/dist/gs/syscall/types.js +45 -1
- package/dist/gs/syscall/types.js.map +1 -1
- package/dist/gs/testing/index.d.ts +1 -0
- package/dist/gs/testing/index.js +2 -0
- package/dist/gs/testing/index.js.map +1 -0
- package/dist/gs/testing/testing.d.ts +77 -0
- package/dist/gs/testing/testing.js +301 -0
- package/dist/gs/testing/testing.js.map +1 -0
- package/dist/gs/time/time.d.ts +41 -4
- package/dist/gs/time/time.js +205 -36
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.d.ts +23 -1
- package/dist/gs/unicode/unicode.js +79 -10
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
- package/dist/gs/unicode/utf8/utf8.js +24 -11
- package/dist/gs/unicode/utf8/utf8.js.map +1 -1
- package/dist/gs/unique/index.d.ts +11 -0
- package/dist/gs/unique/index.js +71 -0
- package/dist/gs/unique/index.js.map +1 -0
- package/go.sum +9 -0
- package/gs/builtin/builtin.ts +239 -8
- package/gs/builtin/channel.ts +22 -0
- package/gs/builtin/runtime-contract.test.ts +126 -0
- package/gs/builtin/slice.ts +259 -50
- package/gs/builtin/type.ts +109 -34
- package/gs/builtin/varRef.ts +38 -1
- package/gs/bytes/buffer.gs.ts +48 -44
- package/gs/bytes/meta.json +8 -3
- package/gs/bytes/reader.gs.ts +20 -19
- package/gs/context/context.test.ts +41 -0
- package/gs/context/context.ts +22 -26
- package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
- package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
- package/gs/embed/index.ts +20 -0
- package/gs/embed/meta.json +5 -0
- package/gs/encoding/json/index.test.ts +15 -1
- package/gs/encoding/json/index.ts +24 -0
- package/gs/errors/errors.test.ts +82 -0
- package/gs/errors/errors.ts +104 -0
- package/gs/fmt/fmt.ts +56 -16
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +73 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +297 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +159 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1005 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +719 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +40 -0
- package/gs/github.com/klauspost/compress/internal/le/index.test.ts +36 -0
- package/gs/github.com/klauspost/compress/internal/le/index.ts +114 -0
- package/gs/go/internal/scannerhooks/index.test.ts +14 -0
- package/gs/go/internal/scannerhooks/index.ts +9 -0
- package/gs/go/scanner/index.test.ts +22 -0
- package/gs/go/scanner/index.ts +47 -0
- package/gs/go/token/index.test.ts +47 -1
- package/gs/go/token/index.ts +570 -4
- package/gs/internal/abi/index.test.ts +18 -0
- package/gs/internal/abi/index.ts +14 -0
- package/gs/internal/bytealg/index.test.ts +18 -0
- package/gs/internal/bytealg/index.ts +16 -0
- package/gs/internal/byteorder/index.test.ts +39 -0
- package/gs/internal/byteorder/index.ts +100 -27
- package/gs/internal/godebug/index.test.ts +16 -0
- package/gs/internal/godebug/index.ts +35 -0
- package/gs/io/fs/index.ts +1 -0
- package/gs/io/fs/meta.json +5 -0
- package/gs/io/fs/readlink.test.ts +43 -0
- package/gs/io/fs/readlink.ts +77 -0
- package/gs/io/fs/walk.test.ts +61 -0
- package/gs/io/fs/walk.ts +9 -9
- package/gs/io/io.ts +174 -31
- package/gs/io/meta.json +10 -2
- package/gs/maps/iter.ts +12 -6
- package/gs/maps/maps.ts +8 -6
- package/gs/math/bits/index.ts +103 -47
- package/gs/math/const.gs.test.ts +11 -5
- package/gs/math/const.gs.ts +5 -6
- package/gs/mime/index.ts +54 -0
- package/gs/net/http/httptest/index.ts +25 -0
- package/gs/net/http/index.test.ts +20 -0
- package/gs/net/http/index.ts +81 -0
- package/gs/os/dir_unix.gs.ts +2 -3
- package/gs/os/types_js.gs.ts +2 -2
- package/gs/path/filepath/match.test.ts +31 -12
- package/gs/path/filepath/match.ts +178 -3
- package/gs/path/filepath/path.test.ts +25 -0
- package/gs/path/filepath/path.ts +159 -5
- package/gs/path/path.ts +20 -5
- package/gs/reflect/index.ts +1 -0
- package/gs/reflect/map.test.ts +19 -0
- package/gs/reflect/map.ts +4 -0
- package/gs/reflect/type.ts +197 -17
- package/gs/runtime/debug/index.test.ts +24 -0
- package/gs/runtime/debug/index.ts +8 -0
- package/gs/runtime/runtime.test.ts +19 -0
- package/gs/runtime/runtime.ts +98 -3
- package/gs/slices/slices.test.ts +94 -0
- package/gs/slices/slices.ts +245 -5
- package/gs/sort/meta.json +7 -0
- package/gs/sort/slice.gs.ts +16 -7
- package/gs/sort/sort.gs.ts +16 -13
- package/gs/strings/builder.ts +4 -3
- package/gs/sync/atomic/type.gs.ts +13 -14
- package/gs/sync/meta.json +3 -1
- package/gs/sync/sync.test.ts +13 -1
- package/gs/sync/sync.ts +27 -0
- package/gs/syscall/constants.ts +39 -24
- package/gs/syscall/errors.ts +10 -0
- package/gs/syscall/fs.ts +195 -0
- package/gs/syscall/js/index.ts +458 -0
- package/gs/syscall/js/meta.json +4 -0
- package/gs/syscall/net.test.ts +85 -0
- package/gs/syscall/types.ts +56 -0
- package/gs/testing/index.ts +1 -0
- package/gs/testing/meta.json +5 -0
- package/gs/testing/testing.test.ts +90 -0
- package/gs/testing/testing.ts +382 -0
- package/gs/time/time.test.ts +106 -0
- package/gs/time/time.ts +278 -57
- package/gs/unicode/unicode.test.ts +25 -0
- package/gs/unicode/unicode.ts +119 -9
- package/gs/unicode/utf8/utf8.test.ts +13 -0
- package/gs/unicode/utf8/utf8.ts +28 -16
- package/gs/unique/index.ts +91 -0
- package/package.json +2 -1
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
package compiler
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"context"
|
|
6
|
+
"errors"
|
|
7
|
+
"io"
|
|
8
|
+
"io/fs"
|
|
9
|
+
"maps"
|
|
10
|
+
"path"
|
|
11
|
+
"slices"
|
|
12
|
+
"strings"
|
|
13
|
+
|
|
14
|
+
gs "github.com/aperturerobotics/goscript"
|
|
15
|
+
jsoniter "github.com/aperturerobotics/json-iterator-lite"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
// OverrideFacts is the immutable compiler-visible view of GoScript overrides.
|
|
19
|
+
type OverrideFacts struct {
|
|
20
|
+
packages map[string]overridePackageFacts
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type overridePackageFacts struct {
|
|
24
|
+
metadata OverrideMetadata
|
|
25
|
+
copyPackage overrideCopyPackage
|
|
26
|
+
dependencies []string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// HasPackage returns true when pkgPath has a GoScript override package.
|
|
30
|
+
func (f *OverrideFacts) HasPackage(pkgPath string) bool {
|
|
31
|
+
if f == nil || pkgPath == "" {
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
_, ok := f.packages[pkgPath]
|
|
35
|
+
return ok
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Metadata returns compiler-visible override metadata for a package path.
|
|
39
|
+
func (f *OverrideFacts) Metadata(pkgPath string) OverrideMetadata {
|
|
40
|
+
if f == nil {
|
|
41
|
+
return newOverrideMetadata()
|
|
42
|
+
}
|
|
43
|
+
pkg := f.packages[pkgPath]
|
|
44
|
+
return cloneOverrideMetadata(pkg.metadata)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// IsMethodAsync returns true when override metadata marks a method async.
|
|
48
|
+
func (f *OverrideFacts) IsMethodAsync(pkgPath, method string) bool {
|
|
49
|
+
if f == nil {
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
52
|
+
pkg := f.packages[pkgPath]
|
|
53
|
+
return pkg.metadata.AsyncMethods[method]
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// IsFunctionAsync returns true when override metadata marks a package-level function async.
|
|
57
|
+
func (f *OverrideFacts) IsFunctionAsync(pkgPath, function string) bool {
|
|
58
|
+
if f == nil {
|
|
59
|
+
return false
|
|
60
|
+
}
|
|
61
|
+
pkg := f.packages[pkgPath]
|
|
62
|
+
return pkg.metadata.AsyncFunctions[function]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
func (f *OverrideFacts) copyPackage(pkgPath string) (overrideCopyPackage, []string, bool) {
|
|
66
|
+
if f == nil {
|
|
67
|
+
return overrideCopyPackage{}, nil, false
|
|
68
|
+
}
|
|
69
|
+
pkg, ok := f.packages[pkgPath]
|
|
70
|
+
if !ok {
|
|
71
|
+
return overrideCopyPackage{}, nil, false
|
|
72
|
+
}
|
|
73
|
+
return cloneOverrideCopyPackage(pkg.copyPackage), slices.Clone(pkg.dependencies), true
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
func (f *OverrideFacts) importPackageRoot(importPath string) (string, bool) {
|
|
77
|
+
if f == nil {
|
|
78
|
+
return "", false
|
|
79
|
+
}
|
|
80
|
+
importPath = strings.TrimPrefix(importPath, "@goscript/")
|
|
81
|
+
importPath = strings.TrimSuffix(importPath, ".js")
|
|
82
|
+
importPath = strings.TrimSuffix(importPath, ".ts")
|
|
83
|
+
if before, ok := strings.CutSuffix(importPath, "/index"); ok {
|
|
84
|
+
importPath = before
|
|
85
|
+
}
|
|
86
|
+
parts := strings.Split(importPath, "/")
|
|
87
|
+
for idx := len(parts); idx > 0; idx-- {
|
|
88
|
+
candidate := strings.Join(parts[:idx], "/")
|
|
89
|
+
if f.HasPackage(candidate) {
|
|
90
|
+
return candidate, true
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return "", false
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
func buildOverrideFacts(ctx context.Context) (*OverrideFacts, []Diagnostic) {
|
|
97
|
+
roots, err := discoverOverridePackageRoots()
|
|
98
|
+
if err != nil {
|
|
99
|
+
return nil, []Diagnostic{overrideError("discover override packages", "", err)}
|
|
100
|
+
}
|
|
101
|
+
paths := make([]string, 0, len(roots))
|
|
102
|
+
for pkgPath := range roots {
|
|
103
|
+
paths = append(paths, pkgPath)
|
|
104
|
+
}
|
|
105
|
+
slices.Sort(paths)
|
|
106
|
+
|
|
107
|
+
facts := &OverrideFacts{packages: make(map[string]overridePackageFacts, len(paths))}
|
|
108
|
+
var diagnostics []Diagnostic
|
|
109
|
+
for _, pkgPath := range paths {
|
|
110
|
+
if err := ctx.Err(); err != nil {
|
|
111
|
+
return facts, []Diagnostic{contextCanceledDiagnostic(err)}
|
|
112
|
+
}
|
|
113
|
+
metadata, err := loadOverrideMetadata(pkgPath)
|
|
114
|
+
if err != nil {
|
|
115
|
+
diagnostics = append(diagnostics, overrideError("read override metadata", pkgPath, err))
|
|
116
|
+
continue
|
|
117
|
+
}
|
|
118
|
+
copyPackage, dependencies, packageDiagnostics := loadOverrideCopyPackage(pkgPath, roots, metadata)
|
|
119
|
+
diagnostics = append(diagnostics, packageDiagnostics...)
|
|
120
|
+
if diagnosticsHaveErrors(packageDiagnostics) {
|
|
121
|
+
continue
|
|
122
|
+
}
|
|
123
|
+
facts.packages[pkgPath] = overridePackageFacts{
|
|
124
|
+
metadata: cloneOverrideMetadata(metadata),
|
|
125
|
+
copyPackage: copyPackage,
|
|
126
|
+
dependencies: dependencies,
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
130
|
+
return facts, diagnostics
|
|
131
|
+
}
|
|
132
|
+
return facts, diagnostics
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
func discoverOverridePackageRoots() (map[string]bool, error) {
|
|
136
|
+
roots := make(map[string]bool)
|
|
137
|
+
if err := fs.WalkDir(gs.GsOverrides, "gs", func(filePath string, entry fs.DirEntry, err error) error {
|
|
138
|
+
if err != nil {
|
|
139
|
+
return err
|
|
140
|
+
}
|
|
141
|
+
if entry.IsDir() || path.Base(filePath) != "index.ts" {
|
|
142
|
+
return nil
|
|
143
|
+
}
|
|
144
|
+
pkgPath := strings.TrimPrefix(path.Dir(filePath), "gs/")
|
|
145
|
+
if pkgPath != "." && pkgPath != "" {
|
|
146
|
+
roots[pkgPath] = true
|
|
147
|
+
}
|
|
148
|
+
return nil
|
|
149
|
+
}); err != nil {
|
|
150
|
+
return nil, err
|
|
151
|
+
}
|
|
152
|
+
return roots, nil
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
func loadOverrideMetadata(pkgPath string) (OverrideMetadata, error) {
|
|
156
|
+
metadata := newOverrideMetadata()
|
|
157
|
+
data, err := gs.GsOverrides.ReadFile("gs/" + pkgPath + "/meta.json")
|
|
158
|
+
if err != nil {
|
|
159
|
+
if errors.Is(err, fs.ErrNotExist) {
|
|
160
|
+
return metadata, nil
|
|
161
|
+
}
|
|
162
|
+
return OverrideMetadata{}, err
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
iter := jsoniter.ParseBytes(data)
|
|
166
|
+
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
|
|
167
|
+
switch field {
|
|
168
|
+
case "dependencies":
|
|
169
|
+
for iter.ReadArray() {
|
|
170
|
+
metadata.Dependencies = append(metadata.Dependencies, iter.ReadString())
|
|
171
|
+
}
|
|
172
|
+
case "asyncMethods":
|
|
173
|
+
for method := iter.ReadObject(); method != ""; method = iter.ReadObject() {
|
|
174
|
+
metadata.AsyncMethods[method] = iter.ReadBool()
|
|
175
|
+
}
|
|
176
|
+
case "asyncFunctions":
|
|
177
|
+
for function := iter.ReadObject(); function != ""; function = iter.ReadObject() {
|
|
178
|
+
metadata.AsyncFunctions[function] = iter.ReadBool()
|
|
179
|
+
}
|
|
180
|
+
default:
|
|
181
|
+
iter.Skip()
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if iter.Error != nil && !errors.Is(iter.Error, io.EOF) {
|
|
185
|
+
return OverrideMetadata{}, iter.Error
|
|
186
|
+
}
|
|
187
|
+
return metadata, nil
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
func loadOverrideCopyPackage(
|
|
191
|
+
pkgPath string,
|
|
192
|
+
roots map[string]bool,
|
|
193
|
+
metadata OverrideMetadata,
|
|
194
|
+
) (overrideCopyPackage, []string, []Diagnostic) {
|
|
195
|
+
if !roots[pkgPath] {
|
|
196
|
+
return overrideCopyPackage{}, nil, []Diagnostic{{
|
|
197
|
+
Severity: DiagnosticSeverityError,
|
|
198
|
+
Code: "goscript/overrides:missing-package",
|
|
199
|
+
Message: "override package does not exist",
|
|
200
|
+
Detail: pkgPath,
|
|
201
|
+
}}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
facts := &OverrideFacts{packages: make(map[string]overridePackageFacts, len(roots))}
|
|
205
|
+
for root := range roots {
|
|
206
|
+
facts.packages[root] = overridePackageFacts{}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
copyPackage := overrideCopyPackage{path: pkgPath}
|
|
210
|
+
dependencySet := make(map[string]bool)
|
|
211
|
+
for _, dependency := range metadata.Dependencies {
|
|
212
|
+
dependency = strings.TrimSpace(dependency)
|
|
213
|
+
if dependency != "" && dependency != pkgPath {
|
|
214
|
+
dependencySet[dependency] = true
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
root := "gs/" + pkgPath
|
|
219
|
+
err := fs.WalkDir(gs.GsOverrides, root, func(filePath string, entry fs.DirEntry, walkErr error) error {
|
|
220
|
+
if walkErr != nil {
|
|
221
|
+
return walkErr
|
|
222
|
+
}
|
|
223
|
+
if entry.IsDir() {
|
|
224
|
+
nestedPkg := strings.TrimPrefix(filePath, "gs/")
|
|
225
|
+
if nestedPkg != pkgPath && roots[nestedPkg] {
|
|
226
|
+
return fs.SkipDir
|
|
227
|
+
}
|
|
228
|
+
return nil
|
|
229
|
+
}
|
|
230
|
+
if !isOverrideSourceFile(filePath) {
|
|
231
|
+
return nil
|
|
232
|
+
}
|
|
233
|
+
data, readErr := gs.GsOverrides.ReadFile(filePath)
|
|
234
|
+
if readErr != nil {
|
|
235
|
+
return readErr
|
|
236
|
+
}
|
|
237
|
+
rel := strings.TrimPrefix(filePath, "gs/")
|
|
238
|
+
copyPackage.files = append(copyPackage.files, overrideCopyFile{
|
|
239
|
+
path: rel,
|
|
240
|
+
data: data,
|
|
241
|
+
})
|
|
242
|
+
for _, imported := range scanOverrideImports(string(data)) {
|
|
243
|
+
dependency, ok := facts.importPackageRoot(imported)
|
|
244
|
+
if ok && dependency != "builtin" && dependency != pkgPath {
|
|
245
|
+
dependencySet[dependency] = true
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return nil
|
|
249
|
+
})
|
|
250
|
+
if err != nil {
|
|
251
|
+
return overrideCopyPackage{}, nil, []Diagnostic{overrideError("read override package", pkgPath, err)}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if len(copyPackage.files) == 0 {
|
|
255
|
+
return overrideCopyPackage{}, nil, []Diagnostic{{
|
|
256
|
+
Severity: DiagnosticSeverityError,
|
|
257
|
+
Code: "goscript/overrides:empty-package",
|
|
258
|
+
Message: "override package does not contain TypeScript source files",
|
|
259
|
+
Detail: pkgPath,
|
|
260
|
+
}}
|
|
261
|
+
}
|
|
262
|
+
slices.SortFunc(copyPackage.files, func(a, b overrideCopyFile) int {
|
|
263
|
+
return strings.Compare(a.path, b.path)
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
dependencies := make([]string, 0, len(dependencySet))
|
|
267
|
+
for dependency := range dependencySet {
|
|
268
|
+
dependencies = append(dependencies, dependency)
|
|
269
|
+
}
|
|
270
|
+
slices.Sort(dependencies)
|
|
271
|
+
return copyPackage, dependencies, nil
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
func newOverrideMetadata() OverrideMetadata {
|
|
275
|
+
return OverrideMetadata{
|
|
276
|
+
AsyncFunctions: make(map[string]bool),
|
|
277
|
+
AsyncMethods: make(map[string]bool),
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
func cloneOverrideMetadata(metadata OverrideMetadata) OverrideMetadata {
|
|
282
|
+
return OverrideMetadata{
|
|
283
|
+
Dependencies: slices.Clone(metadata.Dependencies),
|
|
284
|
+
AsyncFunctions: cloneBoolMap(metadata.AsyncFunctions),
|
|
285
|
+
AsyncMethods: cloneBoolMap(metadata.AsyncMethods),
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
func cloneBoolMap(values map[string]bool) map[string]bool {
|
|
290
|
+
cloned := make(map[string]bool, len(values))
|
|
291
|
+
maps.Copy(cloned, values)
|
|
292
|
+
return cloned
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
func cloneOverrideCopyPackage(pkg overrideCopyPackage) overrideCopyPackage {
|
|
296
|
+
cloned := overrideCopyPackage{
|
|
297
|
+
path: pkg.path,
|
|
298
|
+
files: make([]overrideCopyFile, 0, len(pkg.files)),
|
|
299
|
+
}
|
|
300
|
+
for _, file := range pkg.files {
|
|
301
|
+
cloned.files = append(cloned.files, overrideCopyFile{
|
|
302
|
+
path: file.path,
|
|
303
|
+
data: bytes.Clone(file.data),
|
|
304
|
+
})
|
|
305
|
+
}
|
|
306
|
+
return cloned
|
|
307
|
+
}
|
|
@@ -2,82 +2,56 @@ package compiler
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"context"
|
|
5
|
-
"errors"
|
|
6
|
-
"io"
|
|
7
|
-
"io/fs"
|
|
8
5
|
"os"
|
|
9
|
-
"path"
|
|
10
6
|
"path/filepath"
|
|
11
7
|
"slices"
|
|
12
8
|
"strings"
|
|
13
|
-
|
|
14
|
-
gs "github.com/aperturerobotics/goscript"
|
|
15
|
-
jsoniter "github.com/aperturerobotics/json-iterator-lite"
|
|
16
9
|
)
|
|
17
10
|
|
|
18
11
|
// OverrideMetadata describes compiler-visible facts from a package override.
|
|
19
12
|
type OverrideMetadata struct {
|
|
20
13
|
// Dependencies are override package dependencies.
|
|
21
14
|
Dependencies []string
|
|
15
|
+
// AsyncFunctions maps package-level function names to async status.
|
|
16
|
+
AsyncFunctions map[string]bool
|
|
22
17
|
// AsyncMethods maps Type.Method keys to async status.
|
|
23
18
|
AsyncMethods map[string]bool
|
|
24
19
|
}
|
|
25
20
|
|
|
26
21
|
// OverrideRegistryOwner owns GoScript override package metadata and copy plans.
|
|
27
22
|
type OverrideRegistryOwner struct {
|
|
28
|
-
|
|
29
|
-
packageRootCache map[string]bool
|
|
23
|
+
facts *OverrideFacts
|
|
30
24
|
}
|
|
31
25
|
|
|
32
26
|
// NewOverrideRegistryOwner creates the override registry owner.
|
|
33
27
|
func NewOverrideRegistryOwner() *OverrideRegistryOwner {
|
|
34
|
-
return &OverrideRegistryOwner{
|
|
35
|
-
metadata: make(map[string]*OverrideMetadata),
|
|
36
|
-
}
|
|
28
|
+
return &OverrideRegistryOwner{}
|
|
37
29
|
}
|
|
38
30
|
|
|
39
|
-
//
|
|
40
|
-
func (o *OverrideRegistryOwner)
|
|
31
|
+
// Facts returns the immutable compiler-visible override facts.
|
|
32
|
+
func (o *OverrideRegistryOwner) Facts(ctx context.Context) (*OverrideFacts, []Diagnostic) {
|
|
41
33
|
if o == nil {
|
|
42
34
|
o = NewOverrideRegistryOwner()
|
|
43
35
|
}
|
|
44
|
-
if
|
|
45
|
-
return
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
metadata := &OverrideMetadata{
|
|
49
|
-
AsyncMethods: make(map[string]bool),
|
|
36
|
+
if o.facts != nil {
|
|
37
|
+
return o.facts, nil
|
|
50
38
|
}
|
|
51
|
-
|
|
52
|
-
if
|
|
53
|
-
|
|
54
|
-
o.metadata[pkgPath] = metadata
|
|
55
|
-
return metadata, nil
|
|
56
|
-
}
|
|
57
|
-
return nil, err
|
|
39
|
+
facts, diagnostics := buildOverrideFacts(ctx)
|
|
40
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
41
|
+
return facts, diagnostics
|
|
58
42
|
}
|
|
43
|
+
o.facts = facts
|
|
44
|
+
return facts, diagnostics
|
|
45
|
+
}
|
|
59
46
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
metadata.Dependencies = append(metadata.Dependencies, iter.ReadString())
|
|
66
|
-
}
|
|
67
|
-
case "asyncMethods":
|
|
68
|
-
for method := iter.ReadObject(); method != ""; method = iter.ReadObject() {
|
|
69
|
-
metadata.AsyncMethods[method] = iter.ReadBool()
|
|
70
|
-
}
|
|
71
|
-
default:
|
|
72
|
-
iter.Skip()
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if iter.Error != nil && !errors.Is(iter.Error, io.EOF) {
|
|
76
|
-
return nil, iter.Error
|
|
47
|
+
// Metadata returns compiler-visible override metadata for a package path.
|
|
48
|
+
func (o *OverrideRegistryOwner) Metadata(pkgPath string) (*OverrideMetadata, error) {
|
|
49
|
+
facts, diagnostics := o.Facts(context.Background())
|
|
50
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
51
|
+
return nil, NewCompileError(diagnostics)
|
|
77
52
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return metadata, nil
|
|
53
|
+
metadata := facts.Metadata(pkgPath)
|
|
54
|
+
return &metadata, nil
|
|
81
55
|
}
|
|
82
56
|
|
|
83
57
|
// CopyPlan builds the ordered override package copy plan for a request.
|
|
@@ -107,17 +81,17 @@ func (o *OverrideRegistryOwner) CopyPlan(
|
|
|
107
81
|
Message: "override copy planning requires a package graph",
|
|
108
82
|
}}
|
|
109
83
|
}
|
|
110
|
-
|
|
111
|
-
|
|
84
|
+
facts, diagnostics := o.Facts(ctx)
|
|
85
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
86
|
+
return nil, diagnostics
|
|
112
87
|
}
|
|
113
88
|
|
|
114
|
-
var diagnostics []Diagnostic
|
|
115
89
|
visiting := make(map[string]bool)
|
|
116
90
|
visited := make(map[string]bool)
|
|
117
|
-
diagnostics = append(diagnostics, o.addPackageToPlan(ctx, plan, "builtin", visiting, visited)...)
|
|
91
|
+
diagnostics = append(diagnostics, o.addPackageToPlan(ctx, facts, plan, "builtin", visiting, visited)...)
|
|
118
92
|
for _, node := range graph.Nodes {
|
|
119
93
|
if node.OverrideCandidate {
|
|
120
|
-
diagnostics = append(diagnostics, o.addPackageToPlan(ctx, plan, node.PkgPath, visiting, visited)...)
|
|
94
|
+
diagnostics = append(diagnostics, o.addPackageToPlan(ctx, facts, plan, node.PkgPath, visiting, visited)...)
|
|
121
95
|
}
|
|
122
96
|
}
|
|
123
97
|
if diagnosticsHaveErrors(diagnostics) {
|
|
@@ -181,11 +155,20 @@ func (o *OverrideRegistryOwner) CopyPackages(
|
|
|
181
155
|
|
|
182
156
|
// IsMethodAsync returns true when override metadata marks a method async.
|
|
183
157
|
func (o *OverrideRegistryOwner) IsMethodAsync(pkgPath, method string) (bool, error) {
|
|
184
|
-
|
|
185
|
-
if
|
|
186
|
-
return false,
|
|
158
|
+
facts, diagnostics := o.Facts(context.Background())
|
|
159
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
160
|
+
return false, NewCompileError(diagnostics)
|
|
161
|
+
}
|
|
162
|
+
return facts.IsMethodAsync(pkgPath, method), nil
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// IsFunctionAsync returns true when override metadata marks a package-level function async.
|
|
166
|
+
func (o *OverrideRegistryOwner) IsFunctionAsync(pkgPath, function string) (bool, error) {
|
|
167
|
+
facts, diagnostics := o.Facts(context.Background())
|
|
168
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
169
|
+
return false, NewCompileError(diagnostics)
|
|
187
170
|
}
|
|
188
|
-
return
|
|
171
|
+
return facts.IsFunctionAsync(pkgPath, function), nil
|
|
189
172
|
}
|
|
190
173
|
|
|
191
174
|
type overrideCopyPlan struct {
|
|
@@ -204,6 +187,7 @@ type overrideCopyFile struct {
|
|
|
204
187
|
|
|
205
188
|
func (o *OverrideRegistryOwner) addPackageToPlan(
|
|
206
189
|
ctx context.Context,
|
|
190
|
+
facts *OverrideFacts,
|
|
207
191
|
plan *overrideCopyPlan,
|
|
208
192
|
pkgPath string,
|
|
209
193
|
visiting map[string]bool,
|
|
@@ -228,13 +212,19 @@ func (o *OverrideRegistryOwner) addPackageToPlan(
|
|
|
228
212
|
}}
|
|
229
213
|
}
|
|
230
214
|
|
|
231
|
-
pkg, dependencies,
|
|
232
|
-
if
|
|
233
|
-
return
|
|
215
|
+
pkg, dependencies, ok := facts.copyPackage(pkgPath)
|
|
216
|
+
if !ok {
|
|
217
|
+
return []Diagnostic{{
|
|
218
|
+
Severity: DiagnosticSeverityError,
|
|
219
|
+
Code: "goscript/overrides:missing-package",
|
|
220
|
+
Message: "override package does not exist",
|
|
221
|
+
Detail: pkgPath,
|
|
222
|
+
}}
|
|
234
223
|
}
|
|
235
224
|
visiting[pkgPath] = true
|
|
225
|
+
var diagnostics []Diagnostic
|
|
236
226
|
for _, dependency := range dependencies {
|
|
237
|
-
diagnostics = append(diagnostics, o.addPackageToPlan(ctx, plan, dependency, visiting, visited)...)
|
|
227
|
+
diagnostics = append(diagnostics, o.addPackageToPlan(ctx, facts, plan, dependency, visiting, visited)...)
|
|
238
228
|
}
|
|
239
229
|
delete(visiting, pkgPath)
|
|
240
230
|
if diagnosticsHaveErrors(diagnostics) {
|
|
@@ -246,135 +236,6 @@ func (o *OverrideRegistryOwner) addPackageToPlan(
|
|
|
246
236
|
return diagnostics
|
|
247
237
|
}
|
|
248
238
|
|
|
249
|
-
func (o *OverrideRegistryOwner) loadCopyPackage(pkgPath string) (overrideCopyPackage, []string, []Diagnostic) {
|
|
250
|
-
roots, err := o.packageRoots()
|
|
251
|
-
if err != nil {
|
|
252
|
-
return overrideCopyPackage{}, nil, []Diagnostic{overrideError("discover override packages", "", err)}
|
|
253
|
-
}
|
|
254
|
-
if !roots[pkgPath] {
|
|
255
|
-
return overrideCopyPackage{}, nil, []Diagnostic{{
|
|
256
|
-
Severity: DiagnosticSeverityError,
|
|
257
|
-
Code: "goscript/overrides:missing-package",
|
|
258
|
-
Message: "override package does not exist",
|
|
259
|
-
Detail: pkgPath,
|
|
260
|
-
}}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
metadata, err := o.Metadata(pkgPath)
|
|
264
|
-
if err != nil {
|
|
265
|
-
return overrideCopyPackage{}, nil, []Diagnostic{overrideError("read override metadata", pkgPath, err)}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
copyPackage := overrideCopyPackage{path: pkgPath}
|
|
269
|
-
dependencySet := make(map[string]bool)
|
|
270
|
-
for _, dependency := range metadata.Dependencies {
|
|
271
|
-
dependency = strings.TrimSpace(dependency)
|
|
272
|
-
if dependency != "" && dependency != pkgPath {
|
|
273
|
-
dependencySet[dependency] = true
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
root := "gs/" + pkgPath
|
|
278
|
-
err = fs.WalkDir(gs.GsOverrides, root, func(filePath string, entry fs.DirEntry, walkErr error) error {
|
|
279
|
-
if walkErr != nil {
|
|
280
|
-
return walkErr
|
|
281
|
-
}
|
|
282
|
-
if entry.IsDir() {
|
|
283
|
-
nestedPkg := strings.TrimPrefix(filePath, "gs/")
|
|
284
|
-
if nestedPkg != pkgPath && roots[nestedPkg] {
|
|
285
|
-
return fs.SkipDir
|
|
286
|
-
}
|
|
287
|
-
return nil
|
|
288
|
-
}
|
|
289
|
-
if !isOverrideSourceFile(filePath) {
|
|
290
|
-
return nil
|
|
291
|
-
}
|
|
292
|
-
data, readErr := gs.GsOverrides.ReadFile(filePath)
|
|
293
|
-
if readErr != nil {
|
|
294
|
-
return readErr
|
|
295
|
-
}
|
|
296
|
-
rel := strings.TrimPrefix(filePath, "gs/")
|
|
297
|
-
copyPackage.files = append(copyPackage.files, overrideCopyFile{
|
|
298
|
-
path: rel,
|
|
299
|
-
data: data,
|
|
300
|
-
})
|
|
301
|
-
for _, imported := range scanOverrideImports(string(data)) {
|
|
302
|
-
dependency, ok := o.importPackageRoot(imported)
|
|
303
|
-
if ok && dependency != "builtin" && dependency != pkgPath {
|
|
304
|
-
dependencySet[dependency] = true
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
return nil
|
|
308
|
-
})
|
|
309
|
-
if err != nil {
|
|
310
|
-
return overrideCopyPackage{}, nil, []Diagnostic{overrideError("read override package", pkgPath, err)}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if len(copyPackage.files) == 0 {
|
|
314
|
-
return overrideCopyPackage{}, nil, []Diagnostic{{
|
|
315
|
-
Severity: DiagnosticSeverityError,
|
|
316
|
-
Code: "goscript/overrides:empty-package",
|
|
317
|
-
Message: "override package does not contain TypeScript source files",
|
|
318
|
-
Detail: pkgPath,
|
|
319
|
-
}}
|
|
320
|
-
}
|
|
321
|
-
slices.SortFunc(copyPackage.files, func(a, b overrideCopyFile) int {
|
|
322
|
-
return strings.Compare(a.path, b.path)
|
|
323
|
-
})
|
|
324
|
-
|
|
325
|
-
dependencies := make([]string, 0, len(dependencySet))
|
|
326
|
-
for dependency := range dependencySet {
|
|
327
|
-
dependencies = append(dependencies, dependency)
|
|
328
|
-
}
|
|
329
|
-
slices.Sort(dependencies)
|
|
330
|
-
return copyPackage, dependencies, nil
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
func (o *OverrideRegistryOwner) packageRoots() (map[string]bool, error) {
|
|
334
|
-
if o.packageRootCache != nil {
|
|
335
|
-
return o.packageRootCache, nil
|
|
336
|
-
}
|
|
337
|
-
roots := make(map[string]bool)
|
|
338
|
-
if err := fs.WalkDir(gs.GsOverrides, "gs", func(filePath string, entry fs.DirEntry, err error) error {
|
|
339
|
-
if err != nil {
|
|
340
|
-
return err
|
|
341
|
-
}
|
|
342
|
-
if entry.IsDir() || path.Base(filePath) != "index.ts" {
|
|
343
|
-
return nil
|
|
344
|
-
}
|
|
345
|
-
pkgPath := strings.TrimPrefix(path.Dir(filePath), "gs/")
|
|
346
|
-
if pkgPath != "." && pkgPath != "" {
|
|
347
|
-
roots[pkgPath] = true
|
|
348
|
-
}
|
|
349
|
-
return nil
|
|
350
|
-
}); err != nil {
|
|
351
|
-
return nil, err
|
|
352
|
-
}
|
|
353
|
-
o.packageRootCache = roots
|
|
354
|
-
return roots, nil
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
func (o *OverrideRegistryOwner) importPackageRoot(importPath string) (string, bool) {
|
|
358
|
-
roots, err := o.packageRoots()
|
|
359
|
-
if err != nil {
|
|
360
|
-
return "", false
|
|
361
|
-
}
|
|
362
|
-
importPath = strings.TrimPrefix(importPath, "@goscript/")
|
|
363
|
-
importPath = strings.TrimSuffix(importPath, ".js")
|
|
364
|
-
importPath = strings.TrimSuffix(importPath, ".ts")
|
|
365
|
-
if before, ok := strings.CutSuffix(importPath, "/index"); ok {
|
|
366
|
-
importPath = before
|
|
367
|
-
}
|
|
368
|
-
parts := strings.Split(importPath, "/")
|
|
369
|
-
for idx := len(parts); idx > 0; idx-- {
|
|
370
|
-
candidate := strings.Join(parts[:idx], "/")
|
|
371
|
-
if roots[candidate] {
|
|
372
|
-
return candidate, true
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
return "", false
|
|
376
|
-
}
|
|
377
|
-
|
|
378
239
|
func isOverrideSourceFile(filePath string) bool {
|
|
379
240
|
return strings.HasSuffix(filePath, ".ts") && !strings.HasSuffix(filePath, ".test.ts")
|
|
380
241
|
}
|
|
@@ -35,6 +35,53 @@ func TestOverrideRegistryPlansRuntimeAndOverrideDependencies(t *testing.T) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
func TestOverrideRegistryFactsAreImmutable(t *testing.T) {
|
|
39
|
+
owner := NewOverrideRegistryOwner()
|
|
40
|
+
facts, diagnostics := owner.Facts(context.Background())
|
|
41
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
42
|
+
t.Fatalf("override facts failed: %#v", diagnostics)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
metadata := facts.Metadata("sync")
|
|
46
|
+
if !metadata.AsyncMethods["Map.Load"] {
|
|
47
|
+
t.Fatalf("expected sync Map.Load async metadata")
|
|
48
|
+
}
|
|
49
|
+
metadata.AsyncMethods["Map.Load"] = false
|
|
50
|
+
metadata.Dependencies = append(metadata.Dependencies, "mutated")
|
|
51
|
+
|
|
52
|
+
metadata = facts.Metadata("sync")
|
|
53
|
+
if !metadata.AsyncMethods["Map.Load"] {
|
|
54
|
+
t.Fatalf("override metadata mutation leaked back into facts")
|
|
55
|
+
}
|
|
56
|
+
if slices.Contains(metadata.Dependencies, "mutated") {
|
|
57
|
+
t.Fatalf("override dependency mutation leaked back into facts: %v", metadata.Dependencies)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
pkg, dependencies, ok := facts.copyPackage("fmt")
|
|
61
|
+
if !ok {
|
|
62
|
+
t.Fatalf("missing fmt copy package facts")
|
|
63
|
+
}
|
|
64
|
+
if !slices.Contains(dependencies, "errors") {
|
|
65
|
+
t.Fatalf("expected fmt dependency on errors, got %v", dependencies)
|
|
66
|
+
}
|
|
67
|
+
dependencies = append(dependencies, "mutated")
|
|
68
|
+
if len(pkg.files) == 0 {
|
|
69
|
+
t.Fatalf("expected fmt copy files")
|
|
70
|
+
}
|
|
71
|
+
pkg.files[0].data[0] = '!'
|
|
72
|
+
|
|
73
|
+
pkg, dependencies, ok = facts.copyPackage("fmt")
|
|
74
|
+
if !ok {
|
|
75
|
+
t.Fatalf("missing fmt copy package facts after mutation")
|
|
76
|
+
}
|
|
77
|
+
if slices.Contains(dependencies, "mutated") {
|
|
78
|
+
t.Fatalf("copy dependency mutation leaked back into facts: %v", dependencies)
|
|
79
|
+
}
|
|
80
|
+
if len(pkg.files) == 0 || pkg.files[0].data[0] == '!' {
|
|
81
|
+
t.Fatalf("copy file mutation leaked back into facts")
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
38
85
|
func TestOverrideRegistryCopiesRuntimeAndOverrides(t *testing.T) {
|
|
39
86
|
owner := NewOverrideRegistryOwner()
|
|
40
87
|
req := &CompileRequest{
|