goscript 0.1.4 → 0.2.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 +5 -2
- package/cmd/go_js_wasm_exec/main.go +201 -0
- package/cmd/go_js_wasm_exec/main_test.go +83 -0
- package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +7 -0
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript-wasm/main.go +38 -6
- package/compiler/compile-request.go +12 -9
- package/compiler/compliance_test.go +0 -1
- package/compiler/config.go +2 -0
- package/compiler/diagnostic.go +104 -12
- package/compiler/diagnostic_test.go +106 -0
- package/compiler/gotest/request.go +28 -0
- package/compiler/gotest/runner.go +354 -44
- package/compiler/gotest/runner_test.go +293 -1
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
- package/compiler/gotest/testdata/browserapi/go.mod +3 -0
- package/compiler/index.test.ts +23 -0
- package/compiler/lowered-program.go +33 -24
- package/compiler/lowering.go +746 -194
- package/compiler/lowering_bench_test.go +42 -27
- package/compiler/lowering_internal_test.go +18 -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/protobuf-ts-binding.go +567 -0
- package/compiler/protobuf-ts-binding_test.go +402 -0
- package/compiler/runtime-contract.go +4 -0
- package/compiler/runtime-contract_test.go +2 -0
- package/compiler/semantic-model-types.go +9 -4
- package/compiler/semantic-model.go +282 -70
- package/compiler/semantic-model_test.go +82 -1
- package/compiler/service.go +21 -1
- package/compiler/skeleton_test.go +118 -10
- package/compiler/typescript-emitter.go +128 -13
- package/compiler/wasm/compile_test.go +37 -4
- package/compiler/{wasm_api.go → wasm-api.go} +57 -7
- package/dist/gs/builtin/hostio.js +5 -0
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +13 -2
- package/dist/gs/builtin/slice.js +187 -6
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +13 -5
- package/dist/gs/builtin/type.js +153 -60
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +11 -0
- package/dist/gs/builtin/varRef.js +57 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +10 -3
- package/dist/gs/compress/zlib/index.js +50 -16
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +114 -0
- package/dist/gs/encoding/json/index.js +544 -36
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +101 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +589 -0
- 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 +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +17 -11
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/errors.js +54 -30
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +2 -0
- package/dist/gs/go/scanner/index.js +29 -5
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.js +22 -6
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/index.d.ts +6 -0
- package/dist/gs/hash/index.js +20 -0
- package/dist/gs/hash/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.js +2 -2
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/goarch/index.d.ts +43 -3
- package/dist/gs/internal/goarch/index.js +42 -10
- package/dist/gs/internal/goarch/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js +26 -14
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js +4 -2
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +8 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.d.ts +2 -0
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +5 -0
- package/dist/gs/math/bits/index.js +16 -4
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.d.ts +16 -0
- package/dist/gs/mime/index.js +315 -6
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +12 -0
- package/dist/gs/net/http/httptest/index.js +85 -6
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +300 -5
- package/dist/gs/net/http/index.js +1598 -58
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +1 -1
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.d.ts +1 -0
- package/dist/gs/os/exec.gs.js +4 -8
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/index.d.ts +1 -1
- package/dist/gs/os/index.js +1 -1
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/os/proc.gs.d.ts +4 -0
- package/dist/gs/os/proc.gs.js +12 -6
- package/dist/gs/os/proc.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +1 -1
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/path.js +11 -7
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +5 -4
- package/dist/gs/reflect/index.js +4 -3
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +15 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +25 -6
- package/dist/gs/reflect/type.js +1475 -228
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +14 -6
- package/dist/gs/reflect/types.js +35 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +1 -0
- package/dist/gs/reflect/value.js +83 -41
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +4 -140
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +8 -2
- package/dist/gs/runtime/pprof/index.js +50 -30
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +5 -4
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js +5 -19
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/complex.gs.d.ts +3 -0
- package/dist/gs/strconv/complex.gs.js +148 -0
- package/dist/gs/strconv/complex.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +1 -0
- package/dist/gs/strconv/index.js +1 -0
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/builder.js +1 -1
- package/dist/gs/strings/reader.js +9 -5
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js +15 -7
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.d.ts +5 -0
- package/dist/gs/strings/strings.js +57 -5
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/doc_64.gs.js +7 -6
- package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js +9 -9
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js +2 -2
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/testing/testing.js +55 -13
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.d.ts +24 -1
- package/dist/gs/time/time.js +43 -3
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unique/index.js +7 -1
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +3 -3
- package/go.sum +16 -0
- package/gs/builtin/hostio.test.ts +16 -0
- package/gs/builtin/hostio.ts +7 -0
- package/gs/builtin/runtime-contract.test.ts +246 -21
- package/gs/builtin/slice.ts +269 -24
- package/gs/builtin/type.ts +226 -59
- package/gs/builtin/varRef.ts +85 -2
- package/gs/bytes/buffer.gs.ts +1 -1
- package/gs/bytes/reader.gs.ts +1 -1
- package/gs/compress/zlib/index.test.ts +62 -1
- package/gs/compress/zlib/index.ts +53 -16
- package/gs/compress/zlib/parity.json +51 -0
- package/gs/encoding/json/index.test.ts +360 -6
- package/gs/encoding/json/index.ts +679 -38
- package/gs/encoding/json/parity.json +81 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +373 -3
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +893 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +18 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +17 -11
- 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/byteorder/index.test.ts +2 -2
- package/gs/internal/byteorder/index.ts +2 -2
- package/gs/internal/goarch/index.test.ts +32 -0
- package/gs/internal/goarch/index.ts +45 -13
- package/gs/internal/goarch/parity.json +144 -0
- package/gs/io/fs/fs.ts +26 -14
- package/gs/io/fs/readdir.ts +4 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.ts +1 -0
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +23 -4
- package/gs/math/bits/parity.json +156 -0
- package/gs/mime/index.test.ts +90 -0
- package/gs/mime/index.ts +369 -6
- package/gs/mime/parity.json +36 -0
- package/gs/net/http/httptest/index.test.ts +98 -2
- package/gs/net/http/httptest/index.ts +101 -6
- package/gs/net/http/httptest/parity.json +15 -0
- package/gs/net/http/index.test.ts +781 -12
- package/gs/net/http/index.ts +1860 -139
- package/gs/net/http/meta.json +16 -1
- package/gs/net/http/parity.json +193 -0
- package/gs/os/dir_unix.gs.ts +1 -1
- package/gs/os/error.gs.ts +1 -1
- package/gs/os/exec.gs.ts +4 -8
- package/gs/os/exec_posix.gs.ts +1 -1
- package/gs/os/index.test.ts +9 -0
- package/gs/os/index.ts +1 -0
- package/gs/os/parity.json +9 -0
- package/gs/os/proc.gs.ts +18 -5
- package/gs/os/proc.test.ts +26 -0
- package/gs/os/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +1 -1
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- package/gs/reflect/field.test.ts +37 -15
- package/gs/reflect/function-types.test.ts +518 -22
- package/gs/reflect/index.ts +8 -6
- package/gs/reflect/map.ts +20 -0
- package/gs/reflect/meta.json +6 -4
- package/gs/reflect/parity.json +234 -0
- package/gs/reflect/sliceat.test.ts +156 -0
- package/gs/reflect/structof.test.ts +401 -0
- package/gs/reflect/type.ts +1961 -317
- package/gs/reflect/typefor.test.ts +530 -10
- package/gs/reflect/types.ts +43 -18
- package/gs/reflect/value.ts +105 -45
- package/gs/reflect/visiblefields.ts +5 -168
- package/gs/runtime/parity.json +24 -0
- package/gs/runtime/pprof/index.test.ts +29 -7
- package/gs/runtime/pprof/index.ts +56 -30
- package/gs/runtime/pprof/parity.json +27 -0
- package/gs/runtime/runtime.test.ts +3 -1
- package/gs/runtime/runtime.ts +4 -3
- package/gs/runtime/trace/index.test.ts +5 -3
- package/gs/runtime/trace/index.ts +8 -20
- package/gs/runtime/trace/parity.json +36 -0
- package/gs/strconv/atoi.gs.ts +1 -1
- package/gs/strconv/complex.gs.ts +174 -0
- package/gs/strconv/complex.test.ts +65 -0
- package/gs/strconv/index.ts +1 -0
- package/gs/strconv/parity.json +120 -0
- package/gs/strings/builder.ts +1 -1
- package/gs/strings/parity.json +186 -0
- package/gs/strings/reader.ts +9 -5
- package/gs/strings/replace.ts +15 -7
- package/gs/strings/strings.test.ts +22 -2
- package/gs/strings/strings.ts +64 -6
- package/gs/sync/atomic/doc_64.gs.ts +6 -7
- package/gs/sync/atomic/doc_64.test.ts +43 -0
- package/gs/sync/atomic/type.gs.ts +9 -9
- package/gs/sync/atomic/value.gs.ts +2 -2
- package/gs/syscall/env.ts +29 -14
- package/gs/testing/testing.test.ts +67 -0
- package/gs/testing/testing.ts +87 -19
- package/gs/time/parity.json +225 -0
- package/gs/time/time.test.ts +20 -2
- package/gs/time/time.ts +49 -7
- package/gs/unique/index.ts +7 -1
- package/package.json +4 -2
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -926
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -38
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1361
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
package compiler
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"io"
|
|
5
|
+
"io/fs"
|
|
6
|
+
"maps"
|
|
7
|
+
"path"
|
|
8
|
+
"strings"
|
|
9
|
+
|
|
10
|
+
jsoniter "github.com/aperturerobotics/json-iterator-lite"
|
|
11
|
+
"github.com/pkg/errors"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
type overrideParityStatus string
|
|
15
|
+
|
|
16
|
+
const (
|
|
17
|
+
overrideParityStatusReal overrideParityStatus = "real"
|
|
18
|
+
overrideParityStatusBlocked overrideParityStatus = "blocked"
|
|
19
|
+
overrideParityStatusDeferred overrideParityStatus = "deferred"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
type overrideParityLedger struct {
|
|
23
|
+
SchemaVersion int `json:"schemaVersion"`
|
|
24
|
+
Strict bool `json:"strict"`
|
|
25
|
+
Symbols map[string]overrideParityEntry `json:"symbols"`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type overrideParityEntry struct {
|
|
29
|
+
Status overrideParityStatus `json:"status"`
|
|
30
|
+
Reason string `json:"reason,omitempty"`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
func newOverrideParityLedger() overrideParityLedger {
|
|
34
|
+
return overrideParityLedger{
|
|
35
|
+
Symbols: make(map[string]overrideParityEntry),
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func loadOverrideParityLedger(root overridePackageRoot) (overrideParityLedger, error) {
|
|
40
|
+
ledger := newOverrideParityLedger()
|
|
41
|
+
data, err := fs.ReadFile(root.fsys, path.Join(root.dir, "parity.json"))
|
|
42
|
+
if err != nil {
|
|
43
|
+
if errors.Is(err, fs.ErrNotExist) {
|
|
44
|
+
return ledger, nil
|
|
45
|
+
}
|
|
46
|
+
return overrideParityLedger{}, err
|
|
47
|
+
}
|
|
48
|
+
iter := jsoniter.ParseBytes(data)
|
|
49
|
+
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
|
|
50
|
+
switch field {
|
|
51
|
+
case "schemaVersion":
|
|
52
|
+
ledger.SchemaVersion = iter.ReadInt()
|
|
53
|
+
case "strict":
|
|
54
|
+
ledger.Strict = iter.ReadBool()
|
|
55
|
+
case "symbols":
|
|
56
|
+
for symbol := iter.ReadObject(); symbol != ""; symbol = iter.ReadObject() {
|
|
57
|
+
entry := overrideParityEntry{}
|
|
58
|
+
for entryField := iter.ReadObject(); entryField != ""; entryField = iter.ReadObject() {
|
|
59
|
+
switch entryField {
|
|
60
|
+
case "status":
|
|
61
|
+
entry.Status = overrideParityStatus(iter.ReadString())
|
|
62
|
+
case "reason":
|
|
63
|
+
entry.Reason = iter.ReadString()
|
|
64
|
+
default:
|
|
65
|
+
iter.Skip()
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
ledger.Symbols[symbol] = entry
|
|
69
|
+
}
|
|
70
|
+
default:
|
|
71
|
+
iter.Skip()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if iter.Error != nil && !errors.Is(iter.Error, io.EOF) {
|
|
75
|
+
return overrideParityLedger{}, iter.Error
|
|
76
|
+
}
|
|
77
|
+
if ledger.SchemaVersion != 1 {
|
|
78
|
+
return overrideParityLedger{}, errors.New("parity.json schemaVersion must be 1")
|
|
79
|
+
}
|
|
80
|
+
if ledger.Symbols == nil {
|
|
81
|
+
ledger.Symbols = make(map[string]overrideParityEntry)
|
|
82
|
+
}
|
|
83
|
+
for symbol, entry := range ledger.Symbols {
|
|
84
|
+
if symbol == "" {
|
|
85
|
+
return overrideParityLedger{}, errors.New("parity.json symbol names must not be empty")
|
|
86
|
+
}
|
|
87
|
+
if !entry.Status.valid() {
|
|
88
|
+
return overrideParityLedger{}, errors.New("parity.json contains an unknown status")
|
|
89
|
+
}
|
|
90
|
+
if entry.Status == overrideParityStatusBlocked && strings.TrimSpace(entry.Reason) == "" {
|
|
91
|
+
return overrideParityLedger{}, errors.New("parity.json blocked symbols must include a reason")
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return ledger, nil
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
func (s overrideParityStatus) valid() bool {
|
|
98
|
+
switch s {
|
|
99
|
+
case overrideParityStatusReal,
|
|
100
|
+
overrideParityStatusBlocked,
|
|
101
|
+
overrideParityStatusDeferred:
|
|
102
|
+
return true
|
|
103
|
+
default:
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
func (s overrideParityStatus) requiresExport() bool {
|
|
109
|
+
return s == overrideParityStatusReal
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
func (s overrideParityStatus) forbidsExport() bool {
|
|
113
|
+
return s == overrideParityStatusBlocked
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
func cloneOverrideParityLedger(ledger overrideParityLedger) overrideParityLedger {
|
|
117
|
+
return overrideParityLedger{
|
|
118
|
+
SchemaVersion: ledger.SchemaVersion,
|
|
119
|
+
Strict: ledger.Strict,
|
|
120
|
+
Symbols: maps.Clone(ledger.Symbols),
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -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
|
+
}
|