goscript 0.2.5 → 0.2.7
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-compile.go +7 -0
- package/cmd/goscript/cmd_compile_test.go +83 -0
- package/compiler/compile-request.go +3 -0
- package/compiler/compiler-cache.go +828 -0
- package/compiler/compiler-cache_test.go +705 -0
- package/compiler/config.go +2 -0
- package/compiler/index.test.ts +26 -1
- package/compiler/index.ts +5 -0
- package/compiler/lowered-program.go +31 -20
- package/compiler/lowering.go +349 -93
- package/compiler/lowering_bench_test.go +1 -0
- package/compiler/override-facts.go +309 -8
- package/compiler/override-parity-verifier.go +45 -1
- package/compiler/override-parity-verifier_test.go +100 -0
- package/compiler/override-registry_test.go +1 -0
- package/compiler/package-graph.go +40 -12
- package/compiler/package-graph_test.go +29 -0
- package/compiler/runtime-contract.go +8 -0
- package/compiler/service.go +98 -11
- package/compiler/skeleton_test.go +110 -14
- package/compiler/typescript-emitter.go +120 -23
- package/dist/compiler/index.d.ts +2 -0
- package/dist/compiler/index.js +3 -0
- package/dist/compiler/index.js.map +1 -1
- package/dist/gs/builtin/builtin.d.ts +24 -33
- package/dist/gs/builtin/builtin.js +54 -61
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +1 -0
- package/dist/gs/builtin/hostio.js +1 -1
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/index.d.ts +1 -0
- package/dist/gs/builtin/index.js +1 -0
- package/dist/gs/builtin/index.js.map +1 -1
- package/dist/gs/builtin/panic.d.ts +18 -0
- package/dist/gs/builtin/panic.js +98 -0
- package/dist/gs/builtin/panic.js.map +1 -0
- package/dist/gs/builtin/slice.d.ts +10 -0
- package/dist/gs/builtin/slice.js +110 -53
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.js +15 -3
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +1 -1
- package/dist/gs/builtin/varRef.js +3 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/bytes.gs.js +51 -38
- package/dist/gs/bytes/bytes.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.d.ts +1 -1
- package/dist/gs/bytes/reader.gs.js +6 -7
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/cmp/index.d.ts +1 -1
- package/dist/gs/cmp/index.js +43 -10
- package/dist/gs/cmp/index.js.map +1 -1
- package/dist/gs/context/context.d.ts +2 -2
- package/dist/gs/context/context.js +1 -1
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/embed/index.js +1 -1
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/encoding/binary/index.js +201 -8
- package/dist/gs/encoding/binary/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +5 -0
- package/dist/gs/encoding/json/index.js +388 -25
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.js +17 -24
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.js +129 -35
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1 -1
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -1
- package/dist/gs/internal/bytealg/index.js +43 -8
- package/dist/gs/internal/bytealg/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.d.ts +2 -2
- package/dist/gs/internal/byteorder/index.js +2 -2
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/io/fs/format.js +2 -2
- package/dist/gs/io/fs/format.js.map +1 -1
- package/dist/gs/io/fs/fs.d.ts +1 -1
- package/dist/gs/io/fs/fs.js +1 -1
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/io.d.ts +21 -21
- package/dist/gs/io/io.js +49 -50
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.js +26 -8
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/math/copysign.gs.js +10 -17
- package/dist/gs/math/copysign.gs.js.map +1 -1
- package/dist/gs/math/pow.gs.js +5 -0
- package/dist/gs/math/pow.gs.js.map +1 -1
- package/dist/gs/math/signbit.gs.js +6 -2
- package/dist/gs/math/signbit.gs.js.map +1 -1
- package/dist/gs/mime/index.js +1 -0
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +6 -6
- package/dist/gs/net/http/index.js +507 -43
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/stat.gs.d.ts +2 -2
- package/dist/gs/os/types.gs.d.ts +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +1 -1
- package/dist/gs/os/types_js.gs.js +7 -7
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.d.ts +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/os/zero_copy_posix.gs.d.ts +1 -1
- package/dist/gs/os/zero_copy_posix.gs.js +1 -1
- package/dist/gs/os/zero_copy_posix.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js +8 -4
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.js +216 -42
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/path/match.js +6 -3
- package/dist/gs/path/match.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +5 -4
- package/dist/gs/reflect/type.js +29 -11
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/slices/slices.js +11 -11
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/strconv/atof.gs.js +156 -43
- package/dist/gs/strconv/atof.gs.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.d.ts +3 -2
- package/dist/gs/strconv/atoi.gs.js +86 -67
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/ftoa.gs.js +73 -3
- package/dist/gs/strconv/ftoa.gs.js.map +1 -1
- package/dist/gs/strconv/itoa.gs.d.ts +4 -4
- package/dist/gs/strconv/itoa.gs.js +5 -4
- package/dist/gs/strconv/itoa.gs.js.map +1 -1
- package/dist/gs/strconv/quote.gs.d.ts +1 -1
- package/dist/gs/strconv/quote.gs.js +311 -103
- package/dist/gs/strconv/quote.gs.js.map +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +8 -8
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/strings.js +87 -61
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/doc_64.gs.d.ts +14 -14
- package/dist/gs/sync/atomic/doc_64.gs.js +10 -10
- package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +22 -22
- package/dist/gs/sync/atomic/type.gs.js +4 -4
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/sync.js +50 -12
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +6 -6
- package/dist/gs/syscall/fs.js +1 -1
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/time/time.d.ts +18 -18
- package/dist/gs/time/time.js +58 -55
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/tables.d.ts +11 -0
- package/dist/gs/unicode/tables.js +635 -0
- package/dist/gs/unicode/tables.js.map +1 -0
- package/dist/gs/unicode/unicode.d.ts +58 -38
- package/dist/gs/unicode/unicode.js +362 -278
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/go.sum +13 -0
- package/gs/builtin/builtin.ts +83 -93
- package/gs/builtin/hostio.ts +1 -1
- package/gs/builtin/index.ts +1 -0
- package/gs/builtin/panic.test.ts +189 -0
- package/gs/builtin/panic.ts +107 -0
- package/gs/builtin/runtime-contract.test.ts +5 -5
- package/gs/builtin/slice.test.ts +23 -0
- package/gs/builtin/slice.ts +133 -95
- package/gs/builtin/type.ts +16 -3
- package/gs/builtin/varRef.ts +4 -2
- package/gs/builtin/wide-int.test.ts +41 -0
- package/gs/bytes/bytes.gs.ts +54 -41
- package/gs/bytes/bytes.test.ts +18 -1
- package/gs/bytes/reader.gs.ts +7 -8
- package/gs/cmp/index.test.ts +55 -0
- package/gs/cmp/index.ts +45 -9
- package/gs/context/context.ts +3 -3
- package/gs/embed/index.ts +2 -2
- package/gs/encoding/binary/index.test.ts +104 -0
- package/gs/encoding/binary/index.ts +259 -11
- package/gs/encoding/json/index.test.ts +107 -0
- package/gs/encoding/json/index.ts +400 -29
- package/gs/errors/errors.test.ts +44 -1
- package/gs/errors/errors.ts +15 -31
- package/gs/fmt/fmt.test.ts +70 -2
- package/gs/fmt/fmt.ts +128 -34
- package/gs/golang.org/x/crypto/cryptobyte/index.ts +1 -1
- package/gs/internal/bytealg/index.test.ts +26 -1
- package/gs/internal/bytealg/index.ts +44 -8
- package/gs/internal/byteorder/index.ts +6 -4
- package/gs/io/fs/format.ts +2 -2
- package/gs/io/fs/fs.ts +2 -2
- package/gs/io/fs/stat.test.ts +2 -2
- package/gs/io/fs/sub.test.ts +2 -2
- package/gs/io/fs/walk.test.ts +2 -2
- package/gs/io/io.test.ts +47 -5
- package/gs/io/io.ts +73 -73
- package/gs/io/limit.test.ts +103 -0
- package/gs/math/bits/index.test.ts +128 -0
- package/gs/math/bits/index.ts +26 -8
- package/gs/math/copysign.gs.test.ts +3 -1
- package/gs/math/copysign.gs.ts +10 -22
- package/gs/math/pow.gs.test.ts +4 -5
- package/gs/math/pow.gs.ts +5 -0
- package/gs/math/signbit.gs.test.ts +2 -1
- package/gs/math/signbit.gs.ts +6 -3
- package/gs/mime/index.ts +1 -0
- package/gs/net/http/index.test.ts +683 -2
- package/gs/net/http/index.ts +598 -57
- package/gs/net/http/meta.json +3 -0
- package/gs/os/stat.gs.ts +2 -2
- package/gs/os/types.gs.ts +2 -2
- package/gs/os/types_js.gs.ts +9 -9
- package/gs/os/types_unix.gs.ts +2 -2
- package/gs/os/zero_copy_posix.gs.ts +2 -2
- package/gs/path/filepath/match.test.ts +16 -0
- package/gs/path/filepath/match.ts +8 -4
- package/gs/path/filepath/path.test.ts +91 -9
- package/gs/path/filepath/path.ts +223 -49
- package/gs/path/match.test.ts +32 -0
- package/gs/path/match.ts +6 -3
- package/gs/reflect/deepequal.test.ts +1 -1
- package/gs/reflect/field.test.ts +1 -1
- package/gs/reflect/function-types.test.ts +6 -6
- package/gs/reflect/sliceat.test.ts +13 -13
- package/gs/reflect/structof.test.ts +4 -4
- package/gs/reflect/type.ts +34 -14
- package/gs/reflect/typefor.test.ts +5 -5
- package/gs/runtime/pprof/index.test.ts +20 -0
- package/gs/runtime/trace/index.test.ts +3 -0
- package/gs/slices/slices.test.ts +31 -0
- package/gs/slices/slices.ts +11 -11
- package/gs/strconv/append.test.ts +99 -0
- package/gs/strconv/atof.gs.ts +156 -42
- package/gs/strconv/atof.test.ts +45 -0
- package/gs/strconv/atoi.gs.ts +87 -69
- package/gs/strconv/atoi.test.ts +49 -0
- package/gs/strconv/ftoa.gs.ts +85 -10
- package/gs/strconv/ftoa.test.ts +43 -0
- package/gs/strconv/itoa.gs.ts +10 -9
- package/gs/strconv/quote.gs.ts +335 -108
- package/gs/strconv/quote.test.ts +111 -0
- package/gs/strings/reader.test.ts +10 -10
- package/gs/strings/reader.ts +9 -9
- package/gs/strings/strings.test.ts +18 -5
- package/gs/strings/strings.ts +81 -68
- package/gs/sync/atomic/doc_64.gs.ts +24 -24
- package/gs/sync/atomic/doc_64.test.ts +5 -5
- package/gs/sync/atomic/type.gs.ts +28 -28
- package/gs/sync/sync.test.ts +109 -1
- package/gs/sync/sync.ts +46 -12
- package/gs/syscall/fs.ts +8 -8
- package/gs/syscall/net.test.ts +1 -1
- package/gs/time/parse.test.ts +45 -0
- package/gs/time/time.test.ts +46 -23
- package/gs/time/time.ts +69 -66
- package/gs/unicode/gen.go +198 -0
- package/gs/unicode/tables.ts +646 -0
- package/gs/unicode/unicode.test.ts +69 -0
- package/gs/unicode/unicode.ts +396 -312
- package/package.json +2 -2
- package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +0 -20
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js +0 -134
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/util/conc/index.test.ts +0 -30
- package/gs/github.com/aperturerobotics/util/conc/index.ts +0 -172
- package/gs/github.com/aperturerobotics/util/conc/meta.json +0 -9
|
@@ -4,12 +4,16 @@ import (
|
|
|
4
4
|
"bytes"
|
|
5
5
|
"context"
|
|
6
6
|
"errors"
|
|
7
|
+
"go/ast"
|
|
8
|
+
"go/parser"
|
|
9
|
+
"go/token"
|
|
7
10
|
"io"
|
|
8
11
|
"io/fs"
|
|
9
12
|
"maps"
|
|
10
13
|
"os"
|
|
11
14
|
"path"
|
|
12
15
|
"path/filepath"
|
|
16
|
+
"regexp"
|
|
13
17
|
"slices"
|
|
14
18
|
"strings"
|
|
15
19
|
|
|
@@ -17,16 +21,23 @@ import (
|
|
|
17
21
|
gs "github.com/s4wave/goscript"
|
|
18
22
|
)
|
|
19
23
|
|
|
24
|
+
var (
|
|
25
|
+
overrideBehaviorTestIdentifierPattern = regexp.MustCompile(`\b[A-Za-z_$][A-Za-z0-9_$]*\b`)
|
|
26
|
+
overrideBehaviorTestNamedImportPattern = regexp.MustCompile(`(?s)import\s+(type\s+)?\{([^}]*)\}\s+from\s+['"]\.[^'"]*['"]`)
|
|
27
|
+
overrideBehaviorTestNamespaceImportPattern = regexp.MustCompile(`import\s+\*\s+as\s+([A-Za-z_$][A-Za-z0-9_$]*)\s+from\s+['"]\.[^'"]*['"]`)
|
|
28
|
+
)
|
|
29
|
+
|
|
20
30
|
// OverrideFacts is the immutable compiler-visible view of GoScript overrides.
|
|
21
31
|
type OverrideFacts struct {
|
|
22
32
|
packages map[string]overridePackageFacts
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
type overridePackageFacts struct {
|
|
26
|
-
metadata
|
|
27
|
-
parity
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
metadata OverrideMetadata
|
|
37
|
+
parity overrideParityLedger
|
|
38
|
+
behaviorTestSymbols map[string]bool
|
|
39
|
+
copyPackage overrideCopyPackage
|
|
40
|
+
dependencies []string
|
|
30
41
|
}
|
|
31
42
|
|
|
32
43
|
type overridePackageRoot struct {
|
|
@@ -61,6 +72,14 @@ func (f *OverrideFacts) parityLedger(pkgPath string) overrideParityLedger {
|
|
|
61
72
|
return cloneOverrideParityLedger(pkg.parity)
|
|
62
73
|
}
|
|
63
74
|
|
|
75
|
+
func (f *OverrideFacts) behaviorTestSymbols(pkgPath string) map[string]bool {
|
|
76
|
+
if f == nil {
|
|
77
|
+
return nil
|
|
78
|
+
}
|
|
79
|
+
pkg := f.packages[pkgPath]
|
|
80
|
+
return cloneBoolMap(pkg.behaviorTestSymbols)
|
|
81
|
+
}
|
|
82
|
+
|
|
64
83
|
// IsMethodAsync returns true when override metadata marks a method async.
|
|
65
84
|
func (f *OverrideFacts) IsMethodAsync(pkgPath, method string) bool {
|
|
66
85
|
if f == nil {
|
|
@@ -122,6 +141,7 @@ func buildOverrideFacts(ctx context.Context, overrideDirs []string) (*OverrideFa
|
|
|
122
141
|
slices.Sort(paths)
|
|
123
142
|
|
|
124
143
|
facts := &OverrideFacts{packages: make(map[string]overridePackageFacts, len(paths))}
|
|
144
|
+
goldenBehaviorTests := loadGoldenBehaviorTests()
|
|
125
145
|
for _, pkgPath := range paths {
|
|
126
146
|
if err := ctx.Err(); err != nil {
|
|
127
147
|
return facts, []Diagnostic{contextCanceledDiagnostic(err)}
|
|
@@ -141,11 +161,18 @@ func buildOverrideFacts(ctx context.Context, overrideDirs []string) (*OverrideFa
|
|
|
141
161
|
if diagnosticsHaveErrors(packageDiagnostics) {
|
|
142
162
|
continue
|
|
143
163
|
}
|
|
164
|
+
behaviorTests, err := loadOverrideBehaviorTests(roots[pkgPath], roots)
|
|
165
|
+
if err != nil {
|
|
166
|
+
diagnostics = append(diagnostics, overrideError("read override behavior tests", pkgPath, err))
|
|
167
|
+
continue
|
|
168
|
+
}
|
|
169
|
+
maps.Copy(behaviorTests, goldenBehaviorTests[pkgPath])
|
|
144
170
|
facts.packages[pkgPath] = overridePackageFacts{
|
|
145
|
-
metadata:
|
|
146
|
-
parity:
|
|
147
|
-
|
|
148
|
-
|
|
171
|
+
metadata: cloneOverrideMetadata(metadata),
|
|
172
|
+
parity: cloneOverrideParityLedger(parity),
|
|
173
|
+
behaviorTestSymbols: behaviorTests,
|
|
174
|
+
copyPackage: copyPackage,
|
|
175
|
+
dependencies: dependencies,
|
|
149
176
|
}
|
|
150
177
|
}
|
|
151
178
|
if diagnosticsHaveErrors(diagnostics) {
|
|
@@ -336,6 +363,280 @@ func loadOverrideCopyPackage(
|
|
|
336
363
|
return copyPackage, dependencies, nil
|
|
337
364
|
}
|
|
338
365
|
|
|
366
|
+
func loadOverrideBehaviorTests(
|
|
367
|
+
root overridePackageRoot,
|
|
368
|
+
roots map[string]overridePackageRoot,
|
|
369
|
+
) (map[string]bool, error) {
|
|
370
|
+
symbols := make(map[string]bool)
|
|
371
|
+
err := fs.WalkDir(root.fsys, root.dir, func(filePath string, entry fs.DirEntry, walkErr error) error {
|
|
372
|
+
if walkErr != nil {
|
|
373
|
+
return walkErr
|
|
374
|
+
}
|
|
375
|
+
if entry.IsDir() {
|
|
376
|
+
nestedPkg := strings.TrimPrefix(filePath, root.dir+"/")
|
|
377
|
+
if root.dir == "." {
|
|
378
|
+
nestedPkg = filePath
|
|
379
|
+
} else if nestedPkg != filePath {
|
|
380
|
+
nestedPkg = path.Join(root.pkgPath, nestedPkg)
|
|
381
|
+
}
|
|
382
|
+
if _, ok := roots[nestedPkg]; nestedPkg != root.pkgPath && ok {
|
|
383
|
+
return fs.SkipDir
|
|
384
|
+
}
|
|
385
|
+
return nil
|
|
386
|
+
}
|
|
387
|
+
if !strings.HasSuffix(filePath, ".test.ts") {
|
|
388
|
+
return nil
|
|
389
|
+
}
|
|
390
|
+
data, readErr := fs.ReadFile(root.fsys, filePath)
|
|
391
|
+
if readErr != nil {
|
|
392
|
+
return readErr
|
|
393
|
+
}
|
|
394
|
+
maps.Copy(symbols, scanOverrideBehaviorTestSymbols(string(data)))
|
|
395
|
+
return nil
|
|
396
|
+
})
|
|
397
|
+
if err != nil {
|
|
398
|
+
return nil, err
|
|
399
|
+
}
|
|
400
|
+
return symbols, nil
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
func scanOverrideBehaviorTestSymbols(data string) map[string]bool {
|
|
404
|
+
body := stripTypeScriptCommentsAndStrings(typeScriptBodyWithoutImports(data))
|
|
405
|
+
bodyIdentifiers := make(map[string]bool)
|
|
406
|
+
for _, match := range overrideBehaviorTestIdentifierPattern.FindAllString(body, -1) {
|
|
407
|
+
bodyIdentifiers[match] = true
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
symbols := make(map[string]bool)
|
|
411
|
+
for _, match := range overrideBehaviorTestNamedImportPattern.FindAllStringSubmatch(data, -1) {
|
|
412
|
+
if match[1] != "" {
|
|
413
|
+
continue
|
|
414
|
+
}
|
|
415
|
+
for _, namedImport := range parseNamedTypeScriptExports(match[2], false) {
|
|
416
|
+
if bodyIdentifiers[namedImport.target] {
|
|
417
|
+
symbols[namedImport.source] = true
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
for _, match := range overrideBehaviorTestNamespaceImportPattern.FindAllStringSubmatch(data, -1) {
|
|
422
|
+
namespaceSelectorPattern := regexp.MustCompile(`\b` + regexp.QuoteMeta(match[1]) + `\.([A-Za-z_$][A-Za-z0-9_$]*)\b`)
|
|
423
|
+
for _, selector := range namespaceSelectorPattern.FindAllStringSubmatch(body, -1) {
|
|
424
|
+
symbols[selector[1]] = true
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return symbols
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
func typeScriptBodyWithoutImports(data string) string {
|
|
431
|
+
var body strings.Builder
|
|
432
|
+
inImport := false
|
|
433
|
+
for line := range strings.SplitAfterSeq(data, "\n") {
|
|
434
|
+
trimmed := strings.TrimSpace(line)
|
|
435
|
+
if !inImport && strings.HasPrefix(trimmed, "import ") {
|
|
436
|
+
if !strings.Contains(trimmed, " from ") &&
|
|
437
|
+
!strings.HasPrefix(trimmed, `import "`) &&
|
|
438
|
+
!strings.HasPrefix(trimmed, `import '`) {
|
|
439
|
+
inImport = true
|
|
440
|
+
}
|
|
441
|
+
body.WriteByte('\n')
|
|
442
|
+
continue
|
|
443
|
+
}
|
|
444
|
+
if inImport {
|
|
445
|
+
if strings.Contains(trimmed, " from ") {
|
|
446
|
+
inImport = false
|
|
447
|
+
}
|
|
448
|
+
body.WriteByte('\n')
|
|
449
|
+
continue
|
|
450
|
+
}
|
|
451
|
+
body.WriteString(line)
|
|
452
|
+
}
|
|
453
|
+
return body.String()
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
func stripTypeScriptCommentsAndStrings(data string) string {
|
|
457
|
+
var body strings.Builder
|
|
458
|
+
const (
|
|
459
|
+
modeCode = iota
|
|
460
|
+
modeLineComment
|
|
461
|
+
modeBlockComment
|
|
462
|
+
modeSingleString
|
|
463
|
+
modeDoubleString
|
|
464
|
+
modeTemplateString
|
|
465
|
+
)
|
|
466
|
+
mode := modeCode
|
|
467
|
+
escaped := false
|
|
468
|
+
for i := 0; i < len(data); i++ {
|
|
469
|
+
ch := data[i]
|
|
470
|
+
next := byte(0)
|
|
471
|
+
if i+1 < len(data) {
|
|
472
|
+
next = data[i+1]
|
|
473
|
+
}
|
|
474
|
+
switch mode {
|
|
475
|
+
case modeCode:
|
|
476
|
+
switch {
|
|
477
|
+
case ch == '/' && next == '/':
|
|
478
|
+
body.WriteByte(' ')
|
|
479
|
+
body.WriteByte(' ')
|
|
480
|
+
i++
|
|
481
|
+
mode = modeLineComment
|
|
482
|
+
case ch == '/' && next == '*':
|
|
483
|
+
body.WriteByte(' ')
|
|
484
|
+
body.WriteByte(' ')
|
|
485
|
+
i++
|
|
486
|
+
mode = modeBlockComment
|
|
487
|
+
case ch == '\'':
|
|
488
|
+
body.WriteByte(' ')
|
|
489
|
+
mode = modeSingleString
|
|
490
|
+
case ch == '"':
|
|
491
|
+
body.WriteByte(' ')
|
|
492
|
+
mode = modeDoubleString
|
|
493
|
+
case ch == '`':
|
|
494
|
+
body.WriteByte(' ')
|
|
495
|
+
mode = modeTemplateString
|
|
496
|
+
default:
|
|
497
|
+
body.WriteByte(ch)
|
|
498
|
+
}
|
|
499
|
+
case modeLineComment:
|
|
500
|
+
if ch == '\n' {
|
|
501
|
+
body.WriteByte(ch)
|
|
502
|
+
mode = modeCode
|
|
503
|
+
continue
|
|
504
|
+
}
|
|
505
|
+
body.WriteByte(' ')
|
|
506
|
+
case modeBlockComment:
|
|
507
|
+
if ch == '*' && next == '/' {
|
|
508
|
+
body.WriteByte(' ')
|
|
509
|
+
body.WriteByte(' ')
|
|
510
|
+
i++
|
|
511
|
+
mode = modeCode
|
|
512
|
+
continue
|
|
513
|
+
}
|
|
514
|
+
if ch == '\n' {
|
|
515
|
+
body.WriteByte(ch)
|
|
516
|
+
continue
|
|
517
|
+
}
|
|
518
|
+
body.WriteByte(' ')
|
|
519
|
+
case modeSingleString, modeDoubleString, modeTemplateString:
|
|
520
|
+
quote := byte('\'')
|
|
521
|
+
if mode == modeDoubleString {
|
|
522
|
+
quote = '"'
|
|
523
|
+
}
|
|
524
|
+
if mode == modeTemplateString {
|
|
525
|
+
quote = '`'
|
|
526
|
+
}
|
|
527
|
+
if ch == '\n' {
|
|
528
|
+
body.WriteByte(ch)
|
|
529
|
+
escaped = false
|
|
530
|
+
if mode != modeTemplateString {
|
|
531
|
+
mode = modeCode
|
|
532
|
+
}
|
|
533
|
+
continue
|
|
534
|
+
}
|
|
535
|
+
body.WriteByte(' ')
|
|
536
|
+
if escaped {
|
|
537
|
+
escaped = false
|
|
538
|
+
continue
|
|
539
|
+
}
|
|
540
|
+
if ch == '\\' {
|
|
541
|
+
escaped = true
|
|
542
|
+
continue
|
|
543
|
+
}
|
|
544
|
+
if ch == quote {
|
|
545
|
+
mode = modeCode
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return body.String()
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
func loadGoldenBehaviorTests() map[string]map[string]bool {
|
|
553
|
+
testsDir, ok := findGoldenTestsDir()
|
|
554
|
+
if !ok {
|
|
555
|
+
return nil
|
|
556
|
+
}
|
|
557
|
+
result := make(map[string]map[string]bool)
|
|
558
|
+
_ = filepath.WalkDir(testsDir, func(filePath string, entry fs.DirEntry, err error) error {
|
|
559
|
+
if err != nil || entry.IsDir() || filepath.Ext(filePath) != ".go" {
|
|
560
|
+
return nil
|
|
561
|
+
}
|
|
562
|
+
file, parseErr := parser.ParseFile(token.NewFileSet(), filePath, nil, parser.SkipObjectResolution)
|
|
563
|
+
if parseErr != nil {
|
|
564
|
+
return nil
|
|
565
|
+
}
|
|
566
|
+
importAliases := make(map[string]string)
|
|
567
|
+
dotImports := make(map[string]bool)
|
|
568
|
+
for _, spec := range file.Imports {
|
|
569
|
+
if spec.Path == nil {
|
|
570
|
+
continue
|
|
571
|
+
}
|
|
572
|
+
pkgPath := strings.Trim(spec.Path.Value, `"`)
|
|
573
|
+
if spec.Name != nil {
|
|
574
|
+
switch spec.Name.Name {
|
|
575
|
+
case ".":
|
|
576
|
+
dotImports[pkgPath] = true
|
|
577
|
+
case "_":
|
|
578
|
+
default:
|
|
579
|
+
importAliases[spec.Name.Name] = pkgPath
|
|
580
|
+
}
|
|
581
|
+
continue
|
|
582
|
+
}
|
|
583
|
+
importAliases[path.Base(pkgPath)] = pkgPath
|
|
584
|
+
}
|
|
585
|
+
if len(importAliases) == 0 && len(dotImports) == 0 {
|
|
586
|
+
return nil
|
|
587
|
+
}
|
|
588
|
+
ast.Inspect(file, func(node ast.Node) bool {
|
|
589
|
+
switch expr := node.(type) {
|
|
590
|
+
case *ast.SelectorExpr:
|
|
591
|
+
ident, ok := expr.X.(*ast.Ident)
|
|
592
|
+
if !ok {
|
|
593
|
+
return true
|
|
594
|
+
}
|
|
595
|
+
pkgPath, ok := importAliases[ident.Name]
|
|
596
|
+
if !ok {
|
|
597
|
+
return true
|
|
598
|
+
}
|
|
599
|
+
addBehaviorTestSymbol(result, pkgPath, expr.Sel.Name)
|
|
600
|
+
case *ast.Ident:
|
|
601
|
+
for pkgPath := range dotImports {
|
|
602
|
+
addBehaviorTestSymbol(result, pkgPath, expr.Name)
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return true
|
|
606
|
+
})
|
|
607
|
+
return nil
|
|
608
|
+
})
|
|
609
|
+
return result
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
func findGoldenTestsDir() (string, bool) {
|
|
613
|
+
wd, err := os.Getwd()
|
|
614
|
+
if err != nil {
|
|
615
|
+
return "", false
|
|
616
|
+
}
|
|
617
|
+
for {
|
|
618
|
+
candidate := filepath.Join(wd, "tests", "tests")
|
|
619
|
+
if info, statErr := os.Stat(candidate); statErr == nil && info.IsDir() {
|
|
620
|
+
return candidate, true
|
|
621
|
+
}
|
|
622
|
+
parent := filepath.Dir(wd)
|
|
623
|
+
if parent == wd {
|
|
624
|
+
return "", false
|
|
625
|
+
}
|
|
626
|
+
wd = parent
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
func addBehaviorTestSymbol(index map[string]map[string]bool, pkgPath, symbol string) {
|
|
631
|
+
if pkgPath == "" || symbol == "" {
|
|
632
|
+
return
|
|
633
|
+
}
|
|
634
|
+
if index[pkgPath] == nil {
|
|
635
|
+
index[pkgPath] = make(map[string]bool)
|
|
636
|
+
}
|
|
637
|
+
index[pkgPath][symbol] = true
|
|
638
|
+
}
|
|
639
|
+
|
|
339
640
|
func newOverrideMetadata() OverrideMetadata {
|
|
340
641
|
return OverrideMetadata{
|
|
341
642
|
AsyncFunctions: make(map[string]bool),
|
|
@@ -90,12 +90,41 @@ func (v *OverrideParityVerifier) Verify(
|
|
|
90
90
|
})
|
|
91
91
|
continue
|
|
92
92
|
}
|
|
93
|
-
diagnostics = append(diagnostics, verifyOverrideParityPackage(
|
|
93
|
+
diagnostics = append(diagnostics, verifyOverrideParityPackage(
|
|
94
|
+
node.PkgPath,
|
|
95
|
+
pkg.Types,
|
|
96
|
+
ledger,
|
|
97
|
+
exports,
|
|
98
|
+
facts.behaviorTestSymbols(node.PkgPath),
|
|
99
|
+
)...)
|
|
94
100
|
}
|
|
95
101
|
diagnostics = append(diagnostics, verifyBlockedOverrideUses(graph, facts)...)
|
|
96
102
|
return diagnostics
|
|
97
103
|
}
|
|
98
104
|
|
|
105
|
+
func overrideParityRequiresTypedGraph(graph *PackageGraph, facts *OverrideFacts) bool {
|
|
106
|
+
if graph == nil || facts == nil {
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
109
|
+
for _, node := range graph.Nodes {
|
|
110
|
+
if node == nil || !node.OverrideCandidate {
|
|
111
|
+
continue
|
|
112
|
+
}
|
|
113
|
+
ledger := facts.parityLedger(node.PkgPath)
|
|
114
|
+
if ledger.Strict || len(ledger.Symbols) != 0 {
|
|
115
|
+
return true
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
for _, pkg := range facts.packages {
|
|
119
|
+
for _, entry := range pkg.parity.Symbols {
|
|
120
|
+
if entry.Status == overrideParityStatusBlocked {
|
|
121
|
+
return true
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
|
|
99
128
|
// VerifyNoDeferred reports transient parity entries that remain in packages
|
|
100
129
|
// whose parity surface is expected to be closed.
|
|
101
130
|
func (v *OverrideParityVerifier) VerifyNoDeferred(facts *OverrideFacts, pkgPaths ...string) []Diagnostic {
|
|
@@ -131,12 +160,14 @@ func verifyOverrideParityPackage(
|
|
|
131
160
|
goPkg *types.Package,
|
|
132
161
|
ledger overrideParityLedger,
|
|
133
162
|
tsExports map[string]typeScriptExport,
|
|
163
|
+
behaviorTests map[string]bool,
|
|
134
164
|
) []Diagnostic {
|
|
135
165
|
goExports := exportedPackageSymbols(goPkg)
|
|
136
166
|
goExportSet := make(map[string]bool, len(goExports))
|
|
137
167
|
var diagnostics []Diagnostic
|
|
138
168
|
for _, symbol := range goExports {
|
|
139
169
|
goExportSet[symbol.name] = true
|
|
170
|
+
obj := goPkg.Scope().Lookup(symbol.name)
|
|
140
171
|
entry, ok := ledger.Symbols[symbol.name]
|
|
141
172
|
if ledger.Strict && !ok {
|
|
142
173
|
diagnostics = append(diagnostics, Diagnostic{
|
|
@@ -158,6 +189,14 @@ func verifyOverrideParityPackage(
|
|
|
158
189
|
Detail: pkgPath + "." + symbol.name + " is classified as " + string(entry.Status),
|
|
159
190
|
})
|
|
160
191
|
}
|
|
192
|
+
if entry.Status == overrideParityStatusReal && isPackageLevelFunc(obj) && !behaviorTests[symbol.name] {
|
|
193
|
+
diagnostics = append(diagnostics, Diagnostic{
|
|
194
|
+
Severity: DiagnosticSeverityWarning,
|
|
195
|
+
Code: "goscript/overrides:parity-missing-behavior-test",
|
|
196
|
+
Message: "real override function is missing a locatable behavior test",
|
|
197
|
+
Detail: pkgPath + "." + symbol.name,
|
|
198
|
+
})
|
|
199
|
+
}
|
|
161
200
|
if entry.Status.forbidsExport() && tsExports[symbol.name].present() {
|
|
162
201
|
diagnostics = append(diagnostics, Diagnostic{
|
|
163
202
|
Severity: DiagnosticSeverityError,
|
|
@@ -180,6 +219,11 @@ func verifyOverrideParityPackage(
|
|
|
180
219
|
return diagnostics
|
|
181
220
|
}
|
|
182
221
|
|
|
222
|
+
func isPackageLevelFunc(obj types.Object) bool {
|
|
223
|
+
_, ok := obj.(*types.Func)
|
|
224
|
+
return ok
|
|
225
|
+
}
|
|
226
|
+
|
|
183
227
|
func (symbol goPackageExport) satisfiedBy(export typeScriptExport) bool {
|
|
184
228
|
if symbol.requiresValue {
|
|
185
229
|
return export.value
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
package compiler
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
func TestOverrideParityVerifierWarnsForMissingBehaviorTest(t *testing.T) {
|
|
11
|
+
result, err := compileBehaviorParityFixture(t, "")
|
|
12
|
+
if err != nil {
|
|
13
|
+
t.Fatalf("expected compile without behavior test to warn, not fail: %v\n%#v", err, result.Diagnostics)
|
|
14
|
+
}
|
|
15
|
+
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-missing-behavior-test")
|
|
16
|
+
requireDiagnosticSeverity(t, result.Diagnostics, "goscript/overrides:parity-missing-behavior-test", DiagnosticSeverityWarning)
|
|
17
|
+
|
|
18
|
+
result, err = compileBehaviorParityFixture(t, strings.Join([]string{
|
|
19
|
+
"import { Present } from './index.js'",
|
|
20
|
+
"Present()",
|
|
21
|
+
"",
|
|
22
|
+
}, "\n"))
|
|
23
|
+
if err != nil {
|
|
24
|
+
t.Fatalf("expected compile with behavior test to pass: %v\n%#v", err, result.Diagnostics)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
func TestOverrideParityVerifierIgnoresImportOnlyBehaviorReference(t *testing.T) {
|
|
29
|
+
result, err := compileBehaviorParityFixture(t, strings.Join([]string{
|
|
30
|
+
"import { Present } from './index.js'",
|
|
31
|
+
"const name = 'Present'",
|
|
32
|
+
"void name",
|
|
33
|
+
"",
|
|
34
|
+
}, "\n"))
|
|
35
|
+
if err != nil {
|
|
36
|
+
t.Fatalf("expected import-only behavior test to warn, not fail: %v\n%#v", err, result.Diagnostics)
|
|
37
|
+
}
|
|
38
|
+
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-missing-behavior-test")
|
|
39
|
+
requireDiagnosticSeverity(t, result.Diagnostics, "goscript/overrides:parity-missing-behavior-test", DiagnosticSeverityWarning)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func TestOverrideParityVerifierAcceptsNamespaceBehaviorReference(t *testing.T) {
|
|
43
|
+
result, err := compileBehaviorParityFixture(t, strings.Join([]string{
|
|
44
|
+
"import * as lib from './index.js'",
|
|
45
|
+
"lib.Present()",
|
|
46
|
+
"",
|
|
47
|
+
}, "\n"))
|
|
48
|
+
if err != nil {
|
|
49
|
+
t.Fatalf("expected namespace behavior test to pass: %v\n%#v", err, result.Diagnostics)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func compileBehaviorParityFixture(t *testing.T, behaviorTest string) (*CompilationResult, error) {
|
|
54
|
+
t.Helper()
|
|
55
|
+
|
|
56
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
57
|
+
"go.mod": "module example.test/behaviorparity\n\ngo 1.25.3\n",
|
|
58
|
+
"main.go": strings.Join([]string{
|
|
59
|
+
"package main",
|
|
60
|
+
"import \"example.test/behaviorparity/lib\"",
|
|
61
|
+
"func main() { lib.Present() }",
|
|
62
|
+
"",
|
|
63
|
+
}, "\n"),
|
|
64
|
+
"lib/lib.go": strings.Join([]string{
|
|
65
|
+
"package lib",
|
|
66
|
+
"func Present() {}",
|
|
67
|
+
"",
|
|
68
|
+
}, "\n"),
|
|
69
|
+
})
|
|
70
|
+
overrideDir := filepath.Join(t.TempDir(), "gs")
|
|
71
|
+
writeFixtureFile(t, overrideDir, "example.test/behaviorparity/lib/index.ts", "export function Present(): void {}\n")
|
|
72
|
+
if behaviorTest != "" {
|
|
73
|
+
writeFixtureFile(t, overrideDir, "example.test/behaviorparity/lib/index.test.ts", behaviorTest)
|
|
74
|
+
}
|
|
75
|
+
writeFixtureFile(t, overrideDir, "example.test/behaviorparity/lib/parity.json", parityFixtureJSON(t, map[string]overrideParityEntry{
|
|
76
|
+
"Present": {Status: overrideParityStatusReal},
|
|
77
|
+
}))
|
|
78
|
+
|
|
79
|
+
comp, err := NewCompiler(&Config{
|
|
80
|
+
Dir: moduleDir,
|
|
81
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
82
|
+
OverrideDirs: []string{overrideDir},
|
|
83
|
+
AllDependencies: true,
|
|
84
|
+
}, nil, nil)
|
|
85
|
+
if err != nil {
|
|
86
|
+
t.Fatal(err.Error())
|
|
87
|
+
}
|
|
88
|
+
return comp.CompilePackages(context.Background(), ".")
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
func requireDiagnosticSeverity(t *testing.T, diagnostics []Diagnostic, code string, severity DiagnosticSeverity) {
|
|
92
|
+
t.Helper()
|
|
93
|
+
|
|
94
|
+
for _, diagnostic := range diagnostics {
|
|
95
|
+
if diagnostic.Code == code && diagnostic.Severity == severity {
|
|
96
|
+
return
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
t.Fatalf("missing diagnostic %q with severity %q in %#v", code, severity, diagnostics)
|
|
100
|
+
}
|
|
@@ -1123,6 +1123,7 @@ func compileParityFixture(
|
|
|
1123
1123
|
})
|
|
1124
1124
|
overrideDir := filepath.Join(t.TempDir(), "gs")
|
|
1125
1125
|
writeFixtureFile(t, overrideDir, "example.test/parity/lib/index.ts", index)
|
|
1126
|
+
writeFixtureFile(t, overrideDir, "example.test/parity/lib/index.test.ts", "import { Present } from './index.js'\nPresent()\n")
|
|
1126
1127
|
writeFixtureFile(t, overrideDir, "example.test/parity/lib/parity.json", parityFixtureJSON(t, symbols))
|
|
1127
1128
|
|
|
1128
1129
|
comp, err := NewCompiler(&Config{
|
|
@@ -56,6 +56,13 @@ type PackageGraphOwner struct {
|
|
|
56
56
|
overrideOwner *OverrideRegistryOwner
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
type packageGraphLoadShape int
|
|
60
|
+
|
|
61
|
+
const (
|
|
62
|
+
packageGraphLoadFull packageGraphLoadShape = iota
|
|
63
|
+
packageGraphLoadIdentity
|
|
64
|
+
)
|
|
65
|
+
|
|
59
66
|
// NewPackageGraphOwner creates the package graph owner.
|
|
60
67
|
func NewPackageGraphOwner(overrideOwners ...*OverrideRegistryOwner) *PackageGraphOwner {
|
|
61
68
|
overrideOwner := NewOverrideRegistryOwner()
|
|
@@ -67,6 +74,15 @@ func NewPackageGraphOwner(overrideOwners ...*OverrideRegistryOwner) *PackageGrap
|
|
|
67
74
|
|
|
68
75
|
// Load builds the package graph for a validated request.
|
|
69
76
|
func (o *PackageGraphOwner) Load(ctx context.Context, req *CompileRequest) (*PackageGraph, []Diagnostic) {
|
|
77
|
+
return o.load(ctx, req, packageGraphLoadFull)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// LoadIdentity builds the package identity graph needed for cache lookup.
|
|
81
|
+
func (o *PackageGraphOwner) LoadIdentity(ctx context.Context, req *CompileRequest) (*PackageGraph, []Diagnostic) {
|
|
82
|
+
return o.load(ctx, req, packageGraphLoadIdentity)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func (o *PackageGraphOwner) load(ctx context.Context, req *CompileRequest, shape packageGraphLoadShape) (*PackageGraph, []Diagnostic) {
|
|
70
86
|
if err := ctx.Err(); err != nil {
|
|
71
87
|
return nil, []Diagnostic{{
|
|
72
88
|
Severity: DiagnosticSeverityError,
|
|
@@ -81,18 +97,7 @@ func (o *PackageGraphOwner) Load(ctx context.Context, req *CompileRequest) (*Pac
|
|
|
81
97
|
Env: append(os.Environ(), "GOOS=js", "GOARCH=wasm"),
|
|
82
98
|
BuildFlags: goScriptBuildFlags(req.BuildFlags),
|
|
83
99
|
Tests: req.Tests,
|
|
84
|
-
Mode:
|
|
85
|
-
packages.NeedFiles |
|
|
86
|
-
packages.NeedCompiledGoFiles |
|
|
87
|
-
packages.NeedImports |
|
|
88
|
-
packages.NeedDeps |
|
|
89
|
-
packages.NeedExportFile |
|
|
90
|
-
packages.NeedTypes |
|
|
91
|
-
packages.NeedSyntax |
|
|
92
|
-
packages.NeedTypesInfo |
|
|
93
|
-
packages.NeedTypesSizes |
|
|
94
|
-
packages.NeedForTest |
|
|
95
|
-
packages.NeedModule,
|
|
100
|
+
Mode: packageGraphLoadMode(shape),
|
|
96
101
|
}
|
|
97
102
|
pkgs, err := packages.Load(cfg, req.Patterns...)
|
|
98
103
|
if err != nil {
|
|
@@ -170,6 +175,25 @@ func (o *PackageGraphOwner) Load(ctx context.Context, req *CompileRequest) (*Pac
|
|
|
170
175
|
return graph, diagnostics
|
|
171
176
|
}
|
|
172
177
|
|
|
178
|
+
func packageGraphLoadMode(shape packageGraphLoadShape) packages.LoadMode {
|
|
179
|
+
mode := packages.NeedName |
|
|
180
|
+
packages.NeedFiles |
|
|
181
|
+
packages.NeedCompiledGoFiles |
|
|
182
|
+
packages.NeedImports |
|
|
183
|
+
packages.NeedDeps |
|
|
184
|
+
packages.NeedForTest |
|
|
185
|
+
packages.NeedModule
|
|
186
|
+
if shape == packageGraphLoadIdentity {
|
|
187
|
+
return mode
|
|
188
|
+
}
|
|
189
|
+
return mode |
|
|
190
|
+
packages.NeedExportFile |
|
|
191
|
+
packages.NeedTypes |
|
|
192
|
+
packages.NeedSyntax |
|
|
193
|
+
packages.NeedTypesInfo |
|
|
194
|
+
packages.NeedTypesSizes
|
|
195
|
+
}
|
|
196
|
+
|
|
173
197
|
func (o *PackageGraphOwner) collect(
|
|
174
198
|
graph *PackageGraph,
|
|
175
199
|
pkg *packages.Package,
|
|
@@ -326,6 +350,10 @@ func packageBlocklistChain(graph *PackageGraph, blocklist []string) []string {
|
|
|
326
350
|
return nil
|
|
327
351
|
}
|
|
328
352
|
|
|
353
|
+
func packageGraphContainsPackage(graph *PackageGraph, packagePath string) bool {
|
|
354
|
+
return len(packageBlocklistChain(graph, []string{packagePath})) != 0
|
|
355
|
+
}
|
|
356
|
+
|
|
329
357
|
func packagePathBlocklisted(path string, blocklist []string) bool {
|
|
330
358
|
for _, blocked := range blocklist {
|
|
331
359
|
// Match the package exactly or any subpackage, on a path-segment
|
|
@@ -466,6 +466,35 @@ func TestPackageGraphOverrideCandidatesRequirePackageIndex(t *testing.T) {
|
|
|
466
466
|
}
|
|
467
467
|
}
|
|
468
468
|
|
|
469
|
+
func TestPackageGraphLoadIdentityOmitsTypedFacts(t *testing.T) {
|
|
470
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
471
|
+
"go.mod": "module example.test/identitygraph\n\ngo 1.25.3\n",
|
|
472
|
+
"main.go": "package identitygraph\nconst Value = 1\n",
|
|
473
|
+
})
|
|
474
|
+
graph, diagnostics := NewPackageGraphOwner().LoadIdentity(context.Background(), &CompileRequest{
|
|
475
|
+
Dir: moduleDir,
|
|
476
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
477
|
+
Patterns: []string{"."},
|
|
478
|
+
})
|
|
479
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
480
|
+
t.Fatalf("identity graph load failed: %#v", diagnostics)
|
|
481
|
+
}
|
|
482
|
+
node := graph.NodesByPackagePath["example.test/identitygraph"]
|
|
483
|
+
if node == nil {
|
|
484
|
+
t.Fatalf("missing identity graph node: %#v", graph.NodesByPackagePath)
|
|
485
|
+
}
|
|
486
|
+
if len(node.CompiledGoFiles) != 1 || filepath.Base(node.CompiledGoFiles[0]) != "main.go" {
|
|
487
|
+
t.Fatalf("compiled files = %#v, want main.go", node.CompiledGoFiles)
|
|
488
|
+
}
|
|
489
|
+
pkg := graph.packagesByPath["example.test/identitygraph"]
|
|
490
|
+
if pkg == nil {
|
|
491
|
+
t.Fatal("missing loaded package")
|
|
492
|
+
}
|
|
493
|
+
if pkg.Types != nil || pkg.TypesInfo != nil || len(pkg.Syntax) != 0 {
|
|
494
|
+
t.Fatalf("identity graph loaded typed facts: Types=%v TypesInfo=%v Syntax=%d", pkg.Types, pkg.TypesInfo, len(pkg.Syntax))
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
469
498
|
func loadPackageGraph(t *testing.T, req *CompileRequest) *PackageGraph {
|
|
470
499
|
t.Helper()
|
|
471
500
|
|