goscript 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/cmd/go_js_wasm_exec/main.go +201 -0
- package/cmd/go_js_wasm_exec/main_test.go +83 -0
- package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +35 -8
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript/cmd_compile_test.go +105 -6
- package/compiler/build-flags.go +9 -10
- package/compiler/compile-request.go +12 -9
- package/compiler/compliance_test.go +0 -1
- package/compiler/config.go +2 -0
- package/compiler/gotest/request.go +28 -0
- package/compiler/gotest/runner.go +353 -27
- package/compiler/gotest/runner_test.go +400 -1
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
- package/compiler/gotest/testdata/browserapi/go.mod +3 -0
- package/compiler/lowered-program.go +24 -17
- package/compiler/lowering.go +988 -263
- package/compiler/lowering_bench_test.go +364 -0
- package/compiler/override-facts.go +15 -0
- package/compiler/override-parity-verifier.go +450 -0
- package/compiler/override-parity.go +122 -0
- package/compiler/override-registry_test.go +559 -0
- package/compiler/package-graph.go +61 -4
- package/compiler/package-graph_test.go +30 -0
- package/compiler/protobuf-ts-binding.go +514 -0
- package/compiler/protobuf-ts-binding_test.go +172 -0
- package/compiler/semantic-model-types.go +17 -4
- package/compiler/semantic-model.go +709 -72
- package/compiler/semantic-model_test.go +219 -0
- package/compiler/service.go +20 -1
- package/compiler/skeleton_test.go +1008 -20
- package/compiler/typescript-emitter.go +147 -15
- package/dist/gs/builtin/builtin.d.ts +2 -2
- package/dist/gs/builtin/builtin.js +20 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +2 -1
- package/dist/gs/builtin/slice.js +34 -4
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +14 -6
- package/dist/gs/builtin/type.js +224 -64
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +11 -0
- package/dist/gs/builtin/varRef.js +57 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +13 -6
- package/dist/gs/compress/zlib/index.js +131 -35
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/crypto/sha1/index.js +2 -5
- package/dist/gs/crypto/sha1/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.js +2 -5
- package/dist/gs/crypto/sha256/index.js.map +1 -1
- package/dist/gs/crypto/sha512/index.js +2 -5
- package/dist/gs/crypto/sha512/index.js.map +1 -1
- package/dist/gs/embed/index.d.ts +6 -0
- package/dist/gs/embed/index.js +210 -5
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +114 -0
- package/dist/gs/encoding/json/index.js +544 -36
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +3 -3
- package/dist/gs/fmt/fmt.js +29 -16
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.js +54 -30
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +2 -0
- package/dist/gs/go/scanner/index.js +29 -5
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.js +22 -6
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/index.d.ts +6 -0
- package/dist/gs/hash/index.js +20 -0
- package/dist/gs/hash/index.js.map +1 -1
- package/dist/gs/internal/goarch/index.d.ts +43 -3
- package/dist/gs/internal/goarch/index.js +42 -10
- package/dist/gs/internal/goarch/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js +26 -14
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js +8 -4
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +8 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.d.ts +12 -6
- package/dist/gs/io/io.js +87 -42
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +31 -5
- package/dist/gs/math/bits/index.js +29 -28
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.d.ts +16 -0
- package/dist/gs/mime/index.js +315 -6
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +12 -0
- package/dist/gs/net/http/httptest/index.js +85 -6
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +303 -6
- package/dist/gs/net/http/index.js +1615 -58
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +1 -1
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.d.ts +1 -0
- package/dist/gs/os/exec.gs.js +4 -8
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/index.d.ts +1 -1
- package/dist/gs/os/index.js +1 -1
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/os/proc.gs.d.ts +4 -0
- package/dist/gs/os/proc.gs.js +12 -6
- package/dist/gs/os/proc.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +6 -2
- package/dist/gs/os/types_js.gs.js +170 -9
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/path.js +11 -7
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +5 -4
- package/dist/gs/reflect/index.js +4 -3
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +15 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +26 -6
- package/dist/gs/reflect/type.js +1498 -279
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +14 -6
- package/dist/gs/reflect/types.js +35 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +1 -0
- package/dist/gs/reflect/value.js +83 -41
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +4 -140
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +8 -2
- package/dist/gs/runtime/pprof/index.js +50 -30
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +5 -4
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js +5 -19
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/complex.gs.d.ts +3 -0
- package/dist/gs/strconv/complex.gs.js +148 -0
- package/dist/gs/strconv/complex.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +1 -0
- package/dist/gs/strconv/index.js +1 -0
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/builder.js +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +11 -7
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js +15 -7
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.d.ts +5 -0
- package/dist/gs/strings/strings.js +57 -5
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js +9 -9
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js +2 -2
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -1
- package/dist/gs/sync/sync.js +37 -16
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/syscall/js/index.js +9 -0
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/testing/testing.js +59 -15
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.d.ts +24 -1
- package/dist/gs/time/time.js +43 -3
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unique/index.js +7 -1
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +3 -3
- package/go.sum +16 -0
- package/gs/builtin/builtin.ts +25 -2
- package/gs/builtin/runtime-contract.test.ts +260 -18
- package/gs/builtin/slice.ts +51 -4
- package/gs/builtin/type.ts +310 -63
- package/gs/builtin/varRef.ts +85 -2
- package/gs/bytes/buffer.gs.ts +1 -1
- package/gs/bytes/reader.gs.ts +1 -1
- package/gs/compress/zlib/index.test.ts +159 -1
- package/gs/compress/zlib/index.ts +164 -37
- package/gs/compress/zlib/meta.json +4 -1
- package/gs/compress/zlib/parity.json +51 -0
- package/gs/crypto/sha1/index.test.ts +19 -2
- package/gs/crypto/sha1/index.ts +3 -6
- package/gs/crypto/sha256/index.test.ts +14 -2
- package/gs/crypto/sha256/index.ts +3 -6
- package/gs/crypto/sha512/index.test.ts +17 -2
- package/gs/crypto/sha512/index.ts +3 -6
- package/gs/embed/index.test.ts +87 -0
- package/gs/embed/index.ts +229 -5
- package/gs/encoding/json/index.test.ts +360 -6
- package/gs/encoding/json/index.ts +679 -38
- package/gs/encoding/json/parity.json +81 -0
- package/gs/fmt/fmt.test.ts +41 -3
- package/gs/fmt/fmt.ts +40 -17
- package/gs/fmt/meta.json +6 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
- package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
- package/gs/github.com/pkg/errors/errors.ts +54 -30
- package/gs/go/scanner/index.test.ts +39 -56
- package/gs/go/scanner/index.ts +33 -5
- package/gs/go/scanner/parity.json +27 -0
- package/gs/go/token/index.ts +22 -6
- package/gs/hash/index.test.ts +20 -33
- package/gs/hash/index.ts +28 -0
- package/gs/hash/parity.json +21 -0
- package/gs/internal/goarch/index.test.ts +32 -0
- package/gs/internal/goarch/index.ts +45 -13
- package/gs/internal/goarch/parity.json +144 -0
- package/gs/io/fs/fs.ts +26 -14
- package/gs/io/fs/readdir.test.ts +38 -0
- package/gs/io/fs/readdir.ts +8 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.test.ts +77 -6
- package/gs/io/io.ts +115 -52
- package/gs/io/meta.json +7 -1
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +75 -32
- package/gs/math/bits/parity.json +156 -0
- package/gs/mime/index.test.ts +90 -0
- package/gs/mime/index.ts +369 -6
- package/gs/mime/parity.json +36 -0
- package/gs/net/http/httptest/index.test.ts +98 -2
- package/gs/net/http/httptest/index.ts +101 -6
- package/gs/net/http/httptest/parity.json +15 -0
- package/gs/net/http/index.test.ts +797 -12
- package/gs/net/http/index.ts +1874 -136
- package/gs/net/http/meta.json +16 -1
- package/gs/net/http/parity.json +193 -0
- package/gs/os/dir_unix.gs.ts +1 -1
- package/gs/os/error.gs.ts +1 -1
- package/gs/os/exec.gs.ts +4 -8
- package/gs/os/exec_posix.gs.ts +1 -1
- package/gs/os/file_unix_js.test.ts +52 -0
- package/gs/os/index.test.ts +9 -0
- package/gs/os/index.ts +1 -0
- package/gs/os/meta.json +4 -0
- package/gs/os/parity.json +9 -0
- package/gs/os/proc.gs.ts +18 -5
- package/gs/os/proc.test.ts +26 -0
- package/gs/os/readdir.test.ts +56 -0
- package/gs/os/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +170 -9
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- package/gs/reflect/deepequal.test.ts +10 -1
- package/gs/reflect/field.test.ts +37 -15
- package/gs/reflect/function-types.test.ts +518 -22
- package/gs/reflect/index.ts +8 -6
- package/gs/reflect/map.ts +20 -0
- package/gs/reflect/meta.json +6 -4
- package/gs/reflect/parity.json +234 -0
- package/gs/reflect/sliceat.test.ts +156 -0
- package/gs/reflect/structof.test.ts +401 -0
- package/gs/reflect/type.ts +1980 -365
- package/gs/reflect/typefor.test.ts +540 -10
- package/gs/reflect/types.ts +43 -18
- package/gs/reflect/value.ts +105 -45
- package/gs/reflect/visiblefields.ts +5 -168
- package/gs/runtime/parity.json +24 -0
- package/gs/runtime/pprof/index.test.ts +29 -7
- package/gs/runtime/pprof/index.ts +56 -30
- package/gs/runtime/pprof/parity.json +27 -0
- package/gs/runtime/runtime.test.ts +3 -1
- package/gs/runtime/runtime.ts +4 -3
- package/gs/runtime/trace/index.test.ts +5 -3
- package/gs/runtime/trace/index.ts +8 -20
- package/gs/runtime/trace/parity.json +36 -0
- package/gs/strconv/atoi.gs.ts +1 -1
- package/gs/strconv/complex.gs.ts +174 -0
- package/gs/strconv/complex.test.ts +65 -0
- package/gs/strconv/index.ts +1 -0
- package/gs/strconv/parity.json +120 -0
- package/gs/strings/builder.ts +1 -1
- package/gs/strings/meta.json +5 -2
- package/gs/strings/parity.json +186 -0
- package/gs/strings/reader.test.ts +2 -2
- package/gs/strings/reader.ts +11 -7
- package/gs/strings/replace.ts +15 -7
- package/gs/strings/strings.test.ts +22 -2
- package/gs/strings/strings.ts +64 -6
- package/gs/sync/atomic/type.gs.ts +9 -9
- package/gs/sync/atomic/value.gs.ts +2 -2
- package/gs/sync/meta.json +1 -0
- package/gs/sync/sync.test.ts +41 -1
- package/gs/sync/sync.ts +41 -16
- package/gs/syscall/env.ts +29 -14
- package/gs/syscall/js/index.test.ts +18 -0
- package/gs/syscall/js/index.ts +12 -0
- package/gs/testing/testing.test.ts +99 -3
- package/gs/testing/testing.ts +95 -24
- package/gs/time/parity.json +225 -0
- package/gs/time/time.test.ts +20 -2
- package/gs/time/time.ts +49 -7
- package/gs/unique/index.ts +7 -1
- package/package.json +4 -2
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
- /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
package/compiler/lowering.go
CHANGED
|
@@ -24,6 +24,16 @@ type LoweringOwner struct {
|
|
|
24
24
|
overrideOwner *OverrideRegistryOwner
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// LoweringOptions are request-scoped lowering switches.
|
|
28
|
+
type LoweringOptions struct {
|
|
29
|
+
// SourceRoot is the request source root that may contain sibling protobuf TypeScript files.
|
|
30
|
+
SourceRoot string
|
|
31
|
+
// OutputPath is the TypeScript output root used for generated relative imports.
|
|
32
|
+
OutputPath string
|
|
33
|
+
// ProtobufTypeScriptBinding binds .pb.go files to sibling .pb.ts files.
|
|
34
|
+
ProtobufTypeScriptBinding bool
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
// NewLoweringOwner creates the lowering owner.
|
|
28
38
|
func NewLoweringOwner(runtimeOwner *RuntimeContractOwner, overrideOwner *OverrideRegistryOwner) *LoweringOwner {
|
|
29
39
|
if runtimeOwner == nil {
|
|
@@ -39,7 +49,7 @@ func NewLoweringOwner(runtimeOwner *RuntimeContractOwner, overrideOwner *Overrid
|
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
// Build converts the semantic model into the compiler IR.
|
|
42
|
-
func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel) (*LoweredProgram, []Diagnostic) {
|
|
52
|
+
func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel, opts ...LoweringOptions) (*LoweredProgram, []Diagnostic) {
|
|
43
53
|
if err := ctx.Err(); err != nil {
|
|
44
54
|
return nil, []Diagnostic{{
|
|
45
55
|
Severity: DiagnosticSeverityError,
|
|
@@ -55,7 +65,14 @@ func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel) (*Lower
|
|
|
55
65
|
}}
|
|
56
66
|
}
|
|
57
67
|
|
|
68
|
+
var options LoweringOptions
|
|
69
|
+
if len(opts) != 0 {
|
|
70
|
+
options = opts[0]
|
|
71
|
+
}
|
|
72
|
+
|
|
58
73
|
program := &LoweredProgram{}
|
|
74
|
+
lazyPackageVars := make(map[string]map[types.Object]bool, len(model.packages))
|
|
75
|
+
runtimeMethodSets := make(runtimeMethodSetCache)
|
|
59
76
|
semPkgs := make([]*semanticPackage, 0, len(model.packages))
|
|
60
77
|
for _, semPkg := range model.packages {
|
|
61
78
|
semPkgs = append(semPkgs, semPkg)
|
|
@@ -70,7 +87,7 @@ func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel) (*Lower
|
|
|
70
87
|
diagnostics = append(diagnostics, loweringUnsupported("package", semPkg.pkgPath, "missing semantic source package"))
|
|
71
88
|
continue
|
|
72
89
|
}
|
|
73
|
-
loweredPkg, pkgDiagnostics := o.lowerPackage(model, semPkg)
|
|
90
|
+
loweredPkg, pkgDiagnostics := o.lowerPackage(model, semPkg, lazyPackageVars, runtimeMethodSets, options)
|
|
74
91
|
diagnostics = append(diagnostics, pkgDiagnostics...)
|
|
75
92
|
if loweredPkg != nil {
|
|
76
93
|
program.packages = append(program.packages, loweredPkg)
|
|
@@ -82,18 +99,68 @@ func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel) (*Lower
|
|
|
82
99
|
return program, nil
|
|
83
100
|
}
|
|
84
101
|
|
|
85
|
-
func (o *LoweringOwner) lowerPackage(
|
|
102
|
+
func (o *LoweringOwner) lowerPackage(
|
|
103
|
+
model *SemanticModel,
|
|
104
|
+
semPkg *semanticPackage,
|
|
105
|
+
lazyPackageVarsByPkg map[string]map[types.Object]bool,
|
|
106
|
+
runtimeMethodSets runtimeMethodSetCache,
|
|
107
|
+
options LoweringOptions,
|
|
108
|
+
) (*loweredPackage, []Diagnostic) {
|
|
86
109
|
loweredPkg := &loweredPackage{
|
|
87
110
|
pkgPath: semPkg.pkgPath,
|
|
88
111
|
name: semPkg.name,
|
|
89
112
|
}
|
|
90
113
|
declFiles := packageDeclFiles(semPkg)
|
|
91
114
|
outputNames := packageOutputNames(semPkg)
|
|
92
|
-
|
|
93
|
-
|
|
115
|
+
protobufBindings, bindingDiagnostics := protobufTypeScriptBindings(semPkg, options)
|
|
116
|
+
for sourcePath, binding := range protobufBindings {
|
|
117
|
+
outputNames[sourcePath] = binding.outputName
|
|
118
|
+
}
|
|
119
|
+
lazyPackageVars := o.packageLazyVars(semPkg, lazyPackageVarsByPkg, declFiles)
|
|
120
|
+
diagnostics := append([]Diagnostic(nil), bindingDiagnostics...)
|
|
94
121
|
for idx, file := range semPkg.source.Syntax {
|
|
95
122
|
sourcePath := sourceFilePath(semPkg, idx, file)
|
|
96
|
-
|
|
123
|
+
if options.ProtobufTypeScriptBinding && protobufSRPCHasGoScriptReplacement(sourcePath) {
|
|
124
|
+
stub, stubDiagnostics := lowerProtobufSRPCTypeScriptBindingStub(semPkg, sourcePath, options)
|
|
125
|
+
diagnostics = append(diagnostics, stubDiagnostics...)
|
|
126
|
+
if stub != nil {
|
|
127
|
+
loweredPkg.files = append(loweredPkg.files, stub)
|
|
128
|
+
}
|
|
129
|
+
continue
|
|
130
|
+
}
|
|
131
|
+
if binding, ok := protobufBindings[sourcePath]; ok {
|
|
132
|
+
protobufAdapter := !binding.hasOneof && !strings.HasSuffix(filepath.Base(binding.sourcePath), "_srpc.pb.go")
|
|
133
|
+
loweredFile, fileDiagnostics := o.lowerFile(
|
|
134
|
+
model,
|
|
135
|
+
semPkg,
|
|
136
|
+
file,
|
|
137
|
+
sourcePath,
|
|
138
|
+
declFiles,
|
|
139
|
+
outputNames,
|
|
140
|
+
lazyPackageVars,
|
|
141
|
+
lazyPackageVarsByPkg,
|
|
142
|
+
runtimeMethodSets,
|
|
143
|
+
protobufAdapter,
|
|
144
|
+
)
|
|
145
|
+
diagnostics = append(diagnostics, fileDiagnostics...)
|
|
146
|
+
rewriteProtobufTypeScriptBindingFile(loweredFile, binding)
|
|
147
|
+
if loweredFile != nil {
|
|
148
|
+
loweredPkg.files = append(loweredPkg.files, loweredFile)
|
|
149
|
+
}
|
|
150
|
+
continue
|
|
151
|
+
}
|
|
152
|
+
loweredFile, fileDiagnostics := o.lowerFile(
|
|
153
|
+
model,
|
|
154
|
+
semPkg,
|
|
155
|
+
file,
|
|
156
|
+
sourcePath,
|
|
157
|
+
declFiles,
|
|
158
|
+
outputNames,
|
|
159
|
+
lazyPackageVars,
|
|
160
|
+
lazyPackageVarsByPkg,
|
|
161
|
+
runtimeMethodSets,
|
|
162
|
+
false,
|
|
163
|
+
)
|
|
97
164
|
diagnostics = append(diagnostics, fileDiagnostics...)
|
|
98
165
|
if loweredFile != nil {
|
|
99
166
|
loweredPkg.files = append(loweredPkg.files, loweredFile)
|
|
@@ -125,6 +192,9 @@ func (o *LoweringOwner) lowerFile(
|
|
|
125
192
|
declFiles map[types.Object]string,
|
|
126
193
|
outputNames map[string]string,
|
|
127
194
|
lazyPackageVars map[types.Object]bool,
|
|
195
|
+
lazyPackageVarsByPkg map[string]map[types.Object]bool,
|
|
196
|
+
runtimeMethodSets runtimeMethodSetCache,
|
|
197
|
+
protobufTypeScriptAdapter bool,
|
|
128
198
|
) (*loweredFile, []Diagnostic) {
|
|
129
199
|
associatedMethods := o.methodDeclsForFileTypes(semPkg, file)
|
|
130
200
|
relevantImportFiles := map[string]bool{sourcePath: true}
|
|
@@ -146,7 +216,7 @@ func (o *LoweringOwner) lowerFile(
|
|
|
146
216
|
importPaths := make(map[string]string)
|
|
147
217
|
importNames := make(map[string]string)
|
|
148
218
|
importObjects := make(map[*types.PkgName]string)
|
|
149
|
-
localRefs := o.analyzeLocalFileReferences(semPkg, file, sourcePath, associatedMethods, declFiles, outputNames)
|
|
219
|
+
localRefs := o.analyzeLocalFileReferences(semPkg, file, sourcePath, associatedMethods, declFiles, outputNames, runtimeMethodSets)
|
|
150
220
|
reservedImportAliases := localRefs.reservedNames
|
|
151
221
|
seenImport := make(map[string]bool)
|
|
152
222
|
for idx, importFile := range semPkg.source.Syntax {
|
|
@@ -231,18 +301,20 @@ func (o *LoweringOwner) lowerFile(
|
|
|
231
301
|
loweredFile.imports = append(loweredFile.imports, localImports...)
|
|
232
302
|
|
|
233
303
|
ctx := lowerFileContext{
|
|
234
|
-
model:
|
|
235
|
-
semPkg:
|
|
236
|
-
file:
|
|
237
|
-
importAliases:
|
|
238
|
-
importPaths:
|
|
239
|
-
importNames:
|
|
240
|
-
importObjects:
|
|
241
|
-
sourcePath:
|
|
242
|
-
localAliases:
|
|
243
|
-
lazyPackageVars:
|
|
244
|
-
|
|
245
|
-
|
|
304
|
+
model: model,
|
|
305
|
+
semPkg: semPkg,
|
|
306
|
+
file: file,
|
|
307
|
+
importAliases: importAliases,
|
|
308
|
+
importPaths: importPaths,
|
|
309
|
+
importNames: importNames,
|
|
310
|
+
importObjects: importObjects,
|
|
311
|
+
sourcePath: sourcePath,
|
|
312
|
+
localAliases: localRefs.aliases,
|
|
313
|
+
lazyPackageVars: lazyPackageVars,
|
|
314
|
+
lazyPackageVarsByPkg: lazyPackageVarsByPkg,
|
|
315
|
+
tempNames: newTempNameOwner(),
|
|
316
|
+
topLevel: true,
|
|
317
|
+
protobufTSAdapter: protobufTypeScriptAdapter,
|
|
246
318
|
}
|
|
247
319
|
var diagnostics []Diagnostic
|
|
248
320
|
var packageInitCalls []string
|
|
@@ -451,6 +523,24 @@ type localFileReferenceAnalysis struct {
|
|
|
451
523
|
implicitRuntime map[string]bool
|
|
452
524
|
}
|
|
453
525
|
|
|
526
|
+
type runtimeMethodSetCache map[*types.Named][]types.Object
|
|
527
|
+
|
|
528
|
+
func (c runtimeMethodSetCache) methods(named *types.Named) []types.Object {
|
|
529
|
+
if named == nil {
|
|
530
|
+
return nil
|
|
531
|
+
}
|
|
532
|
+
if methods, ok := c[named]; ok {
|
|
533
|
+
return methods
|
|
534
|
+
}
|
|
535
|
+
methodSet := types.NewMethodSet(types.NewPointer(named))
|
|
536
|
+
methods := make([]types.Object, 0, methodSet.Len())
|
|
537
|
+
for method := range methodSet.Methods() {
|
|
538
|
+
methods = append(methods, method.Obj())
|
|
539
|
+
}
|
|
540
|
+
c[named] = methods
|
|
541
|
+
return methods
|
|
542
|
+
}
|
|
543
|
+
|
|
454
544
|
func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
455
545
|
semPkg *semanticPackage,
|
|
456
546
|
file *ast.File,
|
|
@@ -458,6 +548,7 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
458
548
|
associatedMethods []*ast.FuncDecl,
|
|
459
549
|
declFiles map[types.Object]string,
|
|
460
550
|
outputNames map[string]string,
|
|
551
|
+
runtimeMethodSets runtimeMethodSetCache,
|
|
461
552
|
) localFileReferenceAnalysis {
|
|
462
553
|
analysis := localFileReferenceAnalysis{
|
|
463
554
|
reservedNames: make(map[string]bool),
|
|
@@ -469,6 +560,8 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
469
560
|
}
|
|
470
561
|
seenObjects := make(map[types.Object]bool)
|
|
471
562
|
seenTypes := make(map[types.Type]bool)
|
|
563
|
+
seenRuntimeTypes := make(map[types.Type]bool)
|
|
564
|
+
seenRuntimeOwnerTypes := make(map[types.Type]bool)
|
|
472
565
|
var addTypeDeps func(typ types.Type)
|
|
473
566
|
var addRuntimeTypeDeps func(typ types.Type)
|
|
474
567
|
var addRuntimeTypeOwnerDeps func(typ types.Type)
|
|
@@ -636,6 +729,10 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
636
729
|
if typ == nil {
|
|
637
730
|
return
|
|
638
731
|
}
|
|
732
|
+
if seenRuntimeTypes[typ] {
|
|
733
|
+
return
|
|
734
|
+
}
|
|
735
|
+
seenRuntimeTypes[typ] = true
|
|
639
736
|
if alias, ok := typ.(*types.Alias); ok {
|
|
640
737
|
addObject(alias.Obj(), true)
|
|
641
738
|
if args := alias.TypeArgs(); args != nil {
|
|
@@ -651,9 +748,8 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
651
748
|
for method := range named.Methods() {
|
|
652
749
|
addObject(method, true)
|
|
653
750
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
addObject(method.Obj(), true)
|
|
751
|
+
for _, method := range runtimeMethodSets.methods(named) {
|
|
752
|
+
addObject(method, true)
|
|
657
753
|
}
|
|
658
754
|
if args := named.TypeArgs(); args != nil {
|
|
659
755
|
for t := range args.Types() {
|
|
@@ -680,6 +776,10 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
680
776
|
if typ == nil {
|
|
681
777
|
return
|
|
682
778
|
}
|
|
779
|
+
if seenRuntimeOwnerTypes[typ] {
|
|
780
|
+
return
|
|
781
|
+
}
|
|
782
|
+
seenRuntimeOwnerTypes[typ] = true
|
|
683
783
|
if alias, ok := typ.(*types.Alias); ok {
|
|
684
784
|
addObject(alias.Obj(), true)
|
|
685
785
|
if args := alias.TypeArgs(); args != nil {
|
|
@@ -773,6 +873,9 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
773
873
|
}
|
|
774
874
|
ast.Inspect(file, inspect)
|
|
775
875
|
for _, methodDecl := range associatedMethods {
|
|
876
|
+
if sourcePos(semPkg.source, methodDecl.Pos()).file == sourcePath {
|
|
877
|
+
continue
|
|
878
|
+
}
|
|
776
879
|
ast.Inspect(methodDecl, inspect)
|
|
777
880
|
}
|
|
778
881
|
return analysis
|
|
@@ -984,36 +1087,39 @@ func safeParamName(param *types.Var, idx int) string {
|
|
|
984
1087
|
}
|
|
985
1088
|
|
|
986
1089
|
type lowerFileContext struct {
|
|
987
|
-
model
|
|
988
|
-
semPkg
|
|
989
|
-
file
|
|
990
|
-
importAliases
|
|
991
|
-
importPaths
|
|
992
|
-
importNames
|
|
993
|
-
importObjects
|
|
994
|
-
sourcePath
|
|
995
|
-
localAliases
|
|
996
|
-
lazyPackageVars
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1090
|
+
model *SemanticModel
|
|
1091
|
+
semPkg *semanticPackage
|
|
1092
|
+
file *ast.File
|
|
1093
|
+
importAliases map[string]string
|
|
1094
|
+
importPaths map[string]string
|
|
1095
|
+
importNames map[string]string
|
|
1096
|
+
importObjects map[*types.PkgName]string
|
|
1097
|
+
sourcePath string
|
|
1098
|
+
localAliases map[types.Object]string
|
|
1099
|
+
lazyPackageVars map[types.Object]bool
|
|
1100
|
+
lazyPackageVarsByPkg map[string]map[types.Object]bool
|
|
1101
|
+
identAliases map[types.Object]string
|
|
1102
|
+
identAliasRefs map[types.Object]bool
|
|
1103
|
+
tempNames *tempNameOwner
|
|
1104
|
+
signature *types.Signature
|
|
1105
|
+
typeParams map[string]bool
|
|
1106
|
+
staticTypeParams map[string]bool
|
|
1107
|
+
asyncFunction bool
|
|
1108
|
+
functionTypeDepth int
|
|
1109
|
+
deferState *loweredDeferState
|
|
1110
|
+
rangeBranch *loweredRangeBranch
|
|
1111
|
+
rangeBreak bool
|
|
1112
|
+
rangeContinue bool
|
|
1113
|
+
gotoLabels map[string]bool
|
|
1114
|
+
forwardGotos map[string]bool
|
|
1115
|
+
gotoStateLabels map[string]bool
|
|
1116
|
+
gotoStateVar string
|
|
1117
|
+
gotoStateLoop string
|
|
1118
|
+
functionScopedDecls bool
|
|
1119
|
+
loopLabel string
|
|
1120
|
+
switchBreak bool
|
|
1121
|
+
topLevel bool
|
|
1122
|
+
protobufTSAdapter bool
|
|
1017
1123
|
}
|
|
1018
1124
|
|
|
1019
1125
|
type tempNameOwner struct {
|
|
@@ -1124,7 +1230,7 @@ func isConstGenDecl(decl ast.Decl) bool {
|
|
|
1124
1230
|
}
|
|
1125
1231
|
|
|
1126
1232
|
func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([]loweredDecl, []Diagnostic) {
|
|
1127
|
-
|
|
1233
|
+
decls := make([]loweredDecl, 0, len(decl.Specs))
|
|
1128
1234
|
var diagnostics []Diagnostic
|
|
1129
1235
|
for _, spec := range decl.Specs {
|
|
1130
1236
|
switch typed := spec.(type) {
|
|
@@ -1171,7 +1277,7 @@ func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([
|
|
|
1171
1277
|
if _, ok := obj.(*types.Const); !ok && ctx.model.needsVarRef[obj] {
|
|
1172
1278
|
value = o.runtimeOwner.QualifiedHelper(RuntimeHelperVarRef) + "(" + value + ")"
|
|
1173
1279
|
}
|
|
1174
|
-
keyword :=
|
|
1280
|
+
keyword := strings.TrimSpace(declarationKeyword(ctx))
|
|
1175
1281
|
if _, ok := obj.(*types.Const); ok || decl.Tok == token.CONST {
|
|
1176
1282
|
keyword = "const"
|
|
1177
1283
|
}
|
|
@@ -1190,7 +1296,7 @@ func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([
|
|
|
1190
1296
|
code := keyword + " " + declName + ": " + variableType + " = " + value
|
|
1191
1297
|
if lazy {
|
|
1192
1298
|
keyword = "var"
|
|
1193
|
-
code = "var " + declName + ": " + variableType
|
|
1299
|
+
code = "var " + declName + ": " + variableType
|
|
1194
1300
|
}
|
|
1195
1301
|
indexExport := ""
|
|
1196
1302
|
if ctx.topLevel && name.Name != "_" {
|
|
@@ -1402,7 +1508,10 @@ func packageDeclFiles(semPkg *semanticPackage) map[types.Object]string {
|
|
|
1402
1508
|
if semPkg == nil || semPkg.source == nil {
|
|
1403
1509
|
return nil
|
|
1404
1510
|
}
|
|
1405
|
-
|
|
1511
|
+
if len(semPkg.source.Syntax) <= 1 {
|
|
1512
|
+
return nil
|
|
1513
|
+
}
|
|
1514
|
+
declFiles := make(map[types.Object]string, len(semPkg.declarations))
|
|
1406
1515
|
for _, decl := range semPkg.declarations {
|
|
1407
1516
|
if decl.object != nil && decl.position.file != "" {
|
|
1408
1517
|
declFiles[decl.object] = decl.position.file
|
|
@@ -1423,6 +1532,31 @@ func packageOutputNames(semPkg *semanticPackage) map[string]string {
|
|
|
1423
1532
|
return outputNames
|
|
1424
1533
|
}
|
|
1425
1534
|
|
|
1535
|
+
func (o *LoweringOwner) packageLazyVars(
|
|
1536
|
+
semPkg *semanticPackage,
|
|
1537
|
+
cache map[string]map[types.Object]bool,
|
|
1538
|
+
declFiles map[types.Object]string,
|
|
1539
|
+
) map[types.Object]bool {
|
|
1540
|
+
if semPkg == nil {
|
|
1541
|
+
return nil
|
|
1542
|
+
}
|
|
1543
|
+
if cache == nil {
|
|
1544
|
+
if declFiles == nil {
|
|
1545
|
+
declFiles = packageDeclFiles(semPkg)
|
|
1546
|
+
}
|
|
1547
|
+
return o.lazyPackageVars(semPkg, declFiles)
|
|
1548
|
+
}
|
|
1549
|
+
if lazy, ok := cache[semPkg.pkgPath]; ok {
|
|
1550
|
+
return lazy
|
|
1551
|
+
}
|
|
1552
|
+
if declFiles == nil {
|
|
1553
|
+
declFiles = packageDeclFiles(semPkg)
|
|
1554
|
+
}
|
|
1555
|
+
lazy := o.lazyPackageVars(semPkg, declFiles)
|
|
1556
|
+
cache[semPkg.pkgPath] = lazy
|
|
1557
|
+
return lazy
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1426
1560
|
func (o *LoweringOwner) lazyPackageVars(semPkg *semanticPackage, declFiles map[types.Object]string) map[types.Object]bool {
|
|
1427
1561
|
if semPkg == nil || semPkg.source == nil {
|
|
1428
1562
|
return nil
|
|
@@ -1589,7 +1723,7 @@ func (o *LoweringOwner) packageVarIsLazy(ctx lowerFileContext, obj *types.Var) b
|
|
|
1589
1723
|
if semPkg == nil {
|
|
1590
1724
|
return false
|
|
1591
1725
|
}
|
|
1592
|
-
for lazyObj := range o.
|
|
1726
|
+
for lazyObj := range o.packageLazyVars(semPkg, ctx.lazyPackageVarsByPkg, nil) {
|
|
1593
1727
|
if lazyObj != nil && lazyObj.Name() == obj.Name() &&
|
|
1594
1728
|
lazyObj.Pkg() != nil && lazyObj.Pkg().Path() == obj.Pkg().Path() {
|
|
1595
1729
|
return true
|
|
@@ -1606,7 +1740,7 @@ func (o *LoweringOwner) packageVarNameIsLazy(ctx lowerFileContext, pkgPath, name
|
|
|
1606
1740
|
if semPkg == nil {
|
|
1607
1741
|
return false
|
|
1608
1742
|
}
|
|
1609
|
-
for lazyObj := range o.
|
|
1743
|
+
for lazyObj := range o.packageLazyVars(semPkg, ctx.lazyPackageVarsByPkg, nil) {
|
|
1610
1744
|
if lazyObj != nil && lazyObj.Name() == name {
|
|
1611
1745
|
return true
|
|
1612
1746
|
}
|
|
@@ -1962,6 +2096,13 @@ func lowerLargeIntegerConstantValue(value constant.Value) (string, bool) {
|
|
|
1962
2096
|
return value.ExactString(), true
|
|
1963
2097
|
}
|
|
1964
2098
|
|
|
2099
|
+
func lowerWideIntegerConstantValue(value constant.Value) (string, bool) {
|
|
2100
|
+
if value == nil || value.Kind() != constant.Int || constant.BitLen(value) <= 53 {
|
|
2101
|
+
return "", false
|
|
2102
|
+
}
|
|
2103
|
+
return value.ExactString(), true
|
|
2104
|
+
}
|
|
2105
|
+
|
|
1965
2106
|
func lowerConstantStringByteSlice(ctx lowerFileContext, expr ast.Expr) (string, bool) {
|
|
1966
2107
|
value := ctx.semPkg.source.TypesInfo.Types[unwrapParenExpr(expr)].Value
|
|
1967
2108
|
if value == nil || value.Kind() != constant.String {
|
|
@@ -2006,35 +2147,218 @@ func (o *LoweringOwner) lowerGoEmbedValue(
|
|
|
2006
2147
|
typ types.Type,
|
|
2007
2148
|
patterns []string,
|
|
2008
2149
|
) (string, []Diagnostic) {
|
|
2150
|
+
if isEmbedFSType(typ) {
|
|
2151
|
+
return o.lowerGoEmbedFSValue(ctx, patterns)
|
|
2152
|
+
}
|
|
2009
2153
|
if len(patterns) != 1 {
|
|
2010
2154
|
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern list")}
|
|
2011
2155
|
}
|
|
2012
|
-
|
|
2156
|
+
cleanPattern, diagnostics := cleanGoEmbedFilePattern(ctx, patterns[0])
|
|
2157
|
+
if len(diagnostics) != 0 {
|
|
2158
|
+
return "", diagnostics
|
|
2159
|
+
}
|
|
2160
|
+
data, diagnostics := readGoEmbedFile(ctx, cleanPattern)
|
|
2161
|
+
if len(diagnostics) != 0 {
|
|
2162
|
+
return "", diagnostics
|
|
2163
|
+
}
|
|
2164
|
+
if isStringType(typ) {
|
|
2165
|
+
return strconv.Quote(string(data)), nil
|
|
2166
|
+
}
|
|
2167
|
+
if slice, ok := types.Unalias(typ).Underlying().(*types.Slice); ok && isByteType(slice.Elem()) {
|
|
2168
|
+
return byteSliceLiteral(data), nil
|
|
2169
|
+
}
|
|
2170
|
+
diag := loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed target type")
|
|
2171
|
+
diag.Detail = "target type: " + types.TypeString(typ, func(pkg *types.Package) string {
|
|
2172
|
+
if pkg == nil {
|
|
2173
|
+
return ""
|
|
2174
|
+
}
|
|
2175
|
+
return pkg.Path()
|
|
2176
|
+
})
|
|
2177
|
+
return "", []Diagnostic{diag}
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
func (o *LoweringOwner) lowerGoEmbedFSValue(ctx lowerFileContext, patterns []string) (string, []Diagnostic) {
|
|
2181
|
+
embedAlias := ctx.importPaths["embed"]
|
|
2182
|
+
if embedAlias == "" {
|
|
2183
|
+
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed FS import")}
|
|
2184
|
+
}
|
|
2185
|
+
if len(patterns) == 0 {
|
|
2186
|
+
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern list")}
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
filesByPath := make(map[string][]byte)
|
|
2190
|
+
for _, pattern := range patterns {
|
|
2191
|
+
files, diagnostics := expandGoEmbedPattern(ctx, pattern)
|
|
2192
|
+
if len(diagnostics) != 0 {
|
|
2193
|
+
return "", diagnostics
|
|
2194
|
+
}
|
|
2195
|
+
for _, file := range files {
|
|
2196
|
+
filesByPath[file.path] = file.data
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
paths := make([]string, 0, len(filesByPath))
|
|
2200
|
+
for path := range filesByPath {
|
|
2201
|
+
paths = append(paths, path)
|
|
2202
|
+
}
|
|
2203
|
+
slices.Sort(paths)
|
|
2204
|
+
entries := make([]string, 0, len(paths))
|
|
2205
|
+
for _, path := range paths {
|
|
2206
|
+
entries = append(entries, "["+strconv.Quote(path)+", "+byteSliceLiteral(filesByPath[path])+"]")
|
|
2207
|
+
}
|
|
2208
|
+
builtinAlias := o.runtimeOwner.BuiltinImport().Alias
|
|
2209
|
+
return builtinAlias + ".markAsStructValue(new " + embedAlias + ".FS(new Map<string, Uint8Array>([" + strings.Join(entries, ", ") + "])))", nil
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
type goEmbedFile struct {
|
|
2213
|
+
path string
|
|
2214
|
+
data []byte
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
func cleanGoEmbedFilePattern(ctx lowerFileContext, pattern string) (string, []Diagnostic) {
|
|
2218
|
+
cleanPattern, _, diagnostics := cleanGoEmbedPattern(ctx, pattern)
|
|
2219
|
+
if len(diagnostics) != 0 {
|
|
2220
|
+
return "", diagnostics
|
|
2221
|
+
}
|
|
2222
|
+
if strings.Contains(cleanPattern, "*") {
|
|
2223
|
+
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2224
|
+
}
|
|
2225
|
+
info, err := os.Stat(filepath.Join(filepath.Dir(ctx.sourcePath), filepath.FromSlash(cleanPattern)))
|
|
2226
|
+
if err != nil {
|
|
2227
|
+
return "", []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2228
|
+
}
|
|
2229
|
+
if info.IsDir() {
|
|
2230
|
+
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed directory target")}
|
|
2231
|
+
}
|
|
2232
|
+
return cleanPattern, nil
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
func cleanGoEmbedPattern(ctx lowerFileContext, pattern string) (string, bool, []Diagnostic) {
|
|
2236
|
+
pattern = strings.Trim(pattern, "`\"")
|
|
2237
|
+
all := false
|
|
2238
|
+
if strings.HasPrefix(pattern, "all:") {
|
|
2239
|
+
all = true
|
|
2240
|
+
pattern = strings.TrimPrefix(pattern, "all:")
|
|
2241
|
+
}
|
|
2013
2242
|
cleanPattern := path.Clean(pattern)
|
|
2014
2243
|
if pattern == "" ||
|
|
2015
|
-
strings.Contains(pattern, "*") ||
|
|
2016
2244
|
path.IsAbs(pattern) ||
|
|
2017
2245
|
cleanPattern == "." ||
|
|
2018
2246
|
cleanPattern == ".." ||
|
|
2019
2247
|
strings.HasPrefix(cleanPattern, "../") {
|
|
2020
|
-
return "", []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2248
|
+
return "", false, []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2021
2249
|
}
|
|
2022
|
-
|
|
2250
|
+
return cleanPattern, all, nil
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
func expandGoEmbedPattern(ctx lowerFileContext, pattern string) ([]goEmbedFile, []Diagnostic) {
|
|
2254
|
+
cleanPattern, all, diagnostics := cleanGoEmbedPattern(ctx, pattern)
|
|
2255
|
+
if len(diagnostics) != 0 {
|
|
2256
|
+
return nil, diagnostics
|
|
2257
|
+
}
|
|
2258
|
+
pkgDir := filepath.Dir(ctx.sourcePath)
|
|
2259
|
+
paths := []string{filepath.Join(pkgDir, filepath.FromSlash(cleanPattern))}
|
|
2260
|
+
if strings.Contains(cleanPattern, "*") {
|
|
2261
|
+
matches, err := filepath.Glob(filepath.Join(pkgDir, filepath.FromSlash(cleanPattern)))
|
|
2262
|
+
if err != nil {
|
|
2263
|
+
return nil, []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2264
|
+
}
|
|
2265
|
+
if len(matches) == 0 {
|
|
2266
|
+
return nil, []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "go:embed pattern matched no files")}
|
|
2267
|
+
}
|
|
2268
|
+
paths = matches
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
var files []goEmbedFile
|
|
2272
|
+
for _, path := range paths {
|
|
2273
|
+
collected, diagnostics := collectGoEmbedPath(ctx, pkgDir, path, all)
|
|
2274
|
+
if len(diagnostics) != 0 {
|
|
2275
|
+
return nil, diagnostics
|
|
2276
|
+
}
|
|
2277
|
+
files = append(files, collected...)
|
|
2278
|
+
}
|
|
2279
|
+
slices.SortFunc(files, func(a, b goEmbedFile) int {
|
|
2280
|
+
return cmp.Compare(a.path, b.path)
|
|
2281
|
+
})
|
|
2282
|
+
return files, nil
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
func collectGoEmbedPath(ctx lowerFileContext, pkgDir, absPath string, all bool) ([]goEmbedFile, []Diagnostic) {
|
|
2286
|
+
info, err := os.Stat(absPath)
|
|
2023
2287
|
if err != nil {
|
|
2024
|
-
return
|
|
2025
|
-
Severity: DiagnosticSeverityError,
|
|
2026
|
-
Code: "goscript/lowering:embed",
|
|
2027
|
-
Message: "failed to read go:embed file",
|
|
2028
|
-
Detail: ctx.semPkg.pkgPath + ": " + err.Error(),
|
|
2029
|
-
}}
|
|
2288
|
+
return nil, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2030
2289
|
}
|
|
2031
|
-
if
|
|
2032
|
-
|
|
2290
|
+
if !info.IsDir() {
|
|
2291
|
+
file, diagnostics := readGoEmbedAbsFile(ctx, pkgDir, absPath)
|
|
2292
|
+
if len(diagnostics) != 0 {
|
|
2293
|
+
return nil, diagnostics
|
|
2294
|
+
}
|
|
2295
|
+
return []goEmbedFile{file}, nil
|
|
2033
2296
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2297
|
+
|
|
2298
|
+
var files []goEmbedFile
|
|
2299
|
+
if err := filepath.WalkDir(absPath, func(path string, entry os.DirEntry, err error) error {
|
|
2300
|
+
if err != nil {
|
|
2301
|
+
return err
|
|
2302
|
+
}
|
|
2303
|
+
if path != absPath && !all && (strings.HasPrefix(entry.Name(), ".") || strings.HasPrefix(entry.Name(), "_")) {
|
|
2304
|
+
if entry.IsDir() {
|
|
2305
|
+
return filepath.SkipDir
|
|
2306
|
+
}
|
|
2307
|
+
return nil
|
|
2308
|
+
}
|
|
2309
|
+
if entry.IsDir() {
|
|
2310
|
+
return nil
|
|
2311
|
+
}
|
|
2312
|
+
file, diagnostics := readGoEmbedAbsFile(ctx, pkgDir, path)
|
|
2313
|
+
if len(diagnostics) != 0 {
|
|
2314
|
+
return fmt.Errorf("%s", diagnostics[0].Detail)
|
|
2315
|
+
}
|
|
2316
|
+
files = append(files, file)
|
|
2317
|
+
return nil
|
|
2318
|
+
}); err != nil {
|
|
2319
|
+
return nil, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2320
|
+
}
|
|
2321
|
+
if len(files) == 0 {
|
|
2322
|
+
return nil, []Diagnostic{loweringUnsupported("declaration", ctx.semPkg.pkgPath, "go:embed directory matched no files")}
|
|
2323
|
+
}
|
|
2324
|
+
return files, nil
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
func readGoEmbedFile(ctx lowerFileContext, cleanPattern string) ([]byte, []Diagnostic) {
|
|
2328
|
+
file, diagnostics := readGoEmbedAbsFile(ctx, filepath.Dir(ctx.sourcePath), filepath.Join(filepath.Dir(ctx.sourcePath), filepath.FromSlash(cleanPattern)))
|
|
2329
|
+
if len(diagnostics) != 0 {
|
|
2330
|
+
return nil, diagnostics
|
|
2331
|
+
}
|
|
2332
|
+
return file.data, nil
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
func readGoEmbedAbsFile(ctx lowerFileContext, pkgDir, absPath string) (goEmbedFile, []Diagnostic) {
|
|
2336
|
+
relPath, err := filepath.Rel(pkgDir, absPath)
|
|
2337
|
+
if err != nil {
|
|
2338
|
+
return goEmbedFile{}, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2339
|
+
}
|
|
2340
|
+
data, err := os.ReadFile(absPath)
|
|
2341
|
+
if err != nil {
|
|
2342
|
+
return goEmbedFile{}, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2343
|
+
}
|
|
2344
|
+
return goEmbedFile{path: filepath.ToSlash(relPath), data: data}, nil
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2347
|
+
func goEmbedReadDiagnostic(ctx lowerFileContext, err error) Diagnostic {
|
|
2348
|
+
return Diagnostic{
|
|
2349
|
+
Severity: DiagnosticSeverityError,
|
|
2350
|
+
Code: "goscript/lowering:embed",
|
|
2351
|
+
Message: "failed to read go:embed file",
|
|
2352
|
+
Detail: ctx.semPkg.pkgPath + ": " + err.Error(),
|
|
2036
2353
|
}
|
|
2037
|
-
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
func isEmbedFSType(typ types.Type) bool {
|
|
2357
|
+
named, _ := types.Unalias(typ).(*types.Named)
|
|
2358
|
+
if named == nil || named.Obj() == nil || named.Obj().Pkg() == nil {
|
|
2359
|
+
return false
|
|
2360
|
+
}
|
|
2361
|
+
return named.Obj().Pkg().Path() == "embed" && named.Obj().Name() == "FS"
|
|
2038
2362
|
}
|
|
2039
2363
|
|
|
2040
2364
|
func byteSliceLiteral(data []byte) string {
|
|
@@ -2202,6 +2526,7 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2202
2526
|
name: safeIdentifier(semType.name),
|
|
2203
2527
|
typeName: runtimeNamedTypeName(semType.named),
|
|
2204
2528
|
cloneMethod: "clone",
|
|
2529
|
+
fields: make([]loweredStructField, 0, len(semType.fields)),
|
|
2205
2530
|
}
|
|
2206
2531
|
for idx, field := range semType.fields {
|
|
2207
2532
|
structValue := isStructValueType(field.typ)
|
|
@@ -2221,6 +2546,11 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2221
2546
|
runtimeType: o.runtimeTypeInfoExpr(field.typ),
|
|
2222
2547
|
doc: field.doc,
|
|
2223
2548
|
tag: field.tag,
|
|
2549
|
+
pkgPath: field.pkgPath,
|
|
2550
|
+
index: field.index,
|
|
2551
|
+
offset: field.offset,
|
|
2552
|
+
anonymous: field.embedded,
|
|
2553
|
+
exported: field.exported,
|
|
2224
2554
|
structValue: structValue,
|
|
2225
2555
|
arrayValue: isArrayType(field.typ),
|
|
2226
2556
|
})
|
|
@@ -2228,14 +2558,23 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2228
2558
|
|
|
2229
2559
|
methodDecls := o.methodDeclsForType(ctx, semType.named)
|
|
2230
2560
|
explicitMethods := make(map[string]bool, len(methodDecls))
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2561
|
+
if len(methodDecls) != 0 {
|
|
2562
|
+
lowered.methods = make([]loweredFunction, 0, len(methodDecls))
|
|
2563
|
+
for _, methodDecl := range methodDecls {
|
|
2564
|
+
if methodDecl != nil {
|
|
2565
|
+
explicitMethods[methodDecl.Name.Name] = true
|
|
2566
|
+
}
|
|
2234
2567
|
}
|
|
2235
2568
|
}
|
|
2236
2569
|
var diagnostics []Diagnostic
|
|
2237
2570
|
for _, methodDecl := range methodDecls {
|
|
2238
|
-
|
|
2571
|
+
lowerDecl := methodDecl
|
|
2572
|
+
if ctx.protobufTSAdapter && protobufTypeScriptBindingReplacesMethodName(methodDecl.Name.Name) {
|
|
2573
|
+
bodyless := *methodDecl
|
|
2574
|
+
bodyless.Body = nil
|
|
2575
|
+
lowerDecl = &bodyless
|
|
2576
|
+
}
|
|
2577
|
+
method, methodDiagnostics := o.lowerFuncDecl(ctx, lowerDecl)
|
|
2239
2578
|
diagnostics = append(diagnostics, methodDiagnostics...)
|
|
2240
2579
|
if method != nil {
|
|
2241
2580
|
if method.name == "clone" {
|
|
@@ -2287,11 +2626,12 @@ func (o *LoweringOwner) lowerEmbeddedMethodForwarders(
|
|
|
2287
2626
|
async := o.functionAsync(ctx, method)
|
|
2288
2627
|
targetType := o.tsEmbeddedForwarderTargetType(ctx, field.typ)
|
|
2289
2628
|
lowered := loweredFunction{
|
|
2290
|
-
async:
|
|
2291
|
-
name:
|
|
2292
|
-
runtimeName:
|
|
2293
|
-
|
|
2294
|
-
|
|
2629
|
+
async: async,
|
|
2630
|
+
name: methodMemberName(method.Name()),
|
|
2631
|
+
runtimeName: method.Name(),
|
|
2632
|
+
runtimeSignature: o.runtimeMethodSignature(method, make(map[types.Type]bool)),
|
|
2633
|
+
result: asyncResultType("any", async),
|
|
2634
|
+
deferState: &loweredDeferState{},
|
|
2295
2635
|
}
|
|
2296
2636
|
args := make([]string, 0, signature.Params().Len())
|
|
2297
2637
|
for idx := range signature.Params().Len() {
|
|
@@ -2510,6 +2850,9 @@ func (o *LoweringOwner) lowerFuncDecl(ctx lowerFileContext, decl *ast.FuncDecl)
|
|
|
2510
2850
|
deferState: deferState,
|
|
2511
2851
|
namedResults: o.lowerNamedResults(functionCtx, signature),
|
|
2512
2852
|
}
|
|
2853
|
+
if decl.Recv != nil {
|
|
2854
|
+
lowered.runtimeSignature = o.runtimeMethodSignature(fnObj, make(map[types.Type]bool))
|
|
2855
|
+
}
|
|
2513
2856
|
if signature.TypeParams() != nil && signature.TypeParams().Len() != 0 {
|
|
2514
2857
|
lowered.typeParams = signatureTypeParamNames(signature)
|
|
2515
2858
|
lowered.params = append(lowered.params, loweredParam{
|
|
@@ -2652,6 +2995,9 @@ func expressionUsesObject(ctx lowerFileContext, expr ast.Expr, obj types.Object)
|
|
|
2652
2995
|
if expr == nil || obj == nil || ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
2653
2996
|
return false
|
|
2654
2997
|
}
|
|
2998
|
+
if ident, ok := ast.Unparen(expr).(*ast.Ident); ok {
|
|
2999
|
+
return ctx.semPkg.source.TypesInfo.Uses[ident] == obj || ctx.semPkg.source.TypesInfo.Defs[ident] == obj
|
|
3000
|
+
}
|
|
2655
3001
|
uses := false
|
|
2656
3002
|
ast.Inspect(expr, func(node ast.Node) bool {
|
|
2657
3003
|
if uses {
|
|
@@ -2731,9 +3077,22 @@ func (ctx lowerFileContext) withDeferState(deferState *loweredDeferState) lowerF
|
|
|
2731
3077
|
|
|
2732
3078
|
func (ctx lowerFileContext) withLocalScope() lowerFileContext {
|
|
2733
3079
|
ctx.topLevel = false
|
|
3080
|
+
ctx.functionScopedDecls = false
|
|
3081
|
+
return ctx
|
|
3082
|
+
}
|
|
3083
|
+
|
|
3084
|
+
func (ctx lowerFileContext) withFunctionScopedDecls() lowerFileContext {
|
|
3085
|
+
ctx.functionScopedDecls = true
|
|
2734
3086
|
return ctx
|
|
2735
3087
|
}
|
|
2736
3088
|
|
|
3089
|
+
func declarationKeyword(ctx lowerFileContext) string {
|
|
3090
|
+
if ctx.functionScopedDecls {
|
|
3091
|
+
return "var "
|
|
3092
|
+
}
|
|
3093
|
+
return "let "
|
|
3094
|
+
}
|
|
3095
|
+
|
|
2737
3096
|
func (ctx lowerFileContext) withRangeBranch(branch *loweredRangeBranch) lowerFileContext {
|
|
2738
3097
|
ctx.rangeBranch = branch
|
|
2739
3098
|
ctx.rangeBreak = true
|
|
@@ -2821,6 +3180,10 @@ func (o *LoweringOwner) lowerBlock(ctx lowerFileContext, block *ast.BlockStmt) (
|
|
|
2821
3180
|
}
|
|
2822
3181
|
|
|
2823
3182
|
func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]loweredStmt, []Diagnostic) {
|
|
3183
|
+
return o.lowerStmtInto(ctx, stmt, nil)
|
|
3184
|
+
}
|
|
3185
|
+
|
|
3186
|
+
func (o *LoweringOwner) lowerStmtInto(ctx lowerFileContext, stmt ast.Stmt, out []loweredStmt) ([]loweredStmt, []Diagnostic) {
|
|
2824
3187
|
switch typed := stmt.(type) {
|
|
2825
3188
|
case *ast.DeclStmt:
|
|
2826
3189
|
decls, diagnostics := o.lowerDecl(ctx, typed.Decl)
|
|
@@ -2836,27 +3199,28 @@ func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
2836
3199
|
stmts = append(stmts, loweredStmt{text: strings.TrimRight(b.String(), "\n")})
|
|
2837
3200
|
}
|
|
2838
3201
|
}
|
|
2839
|
-
return stmts, diagnostics
|
|
3202
|
+
return append(out, stmts...), diagnostics
|
|
2840
3203
|
case *ast.BlockStmt:
|
|
2841
3204
|
body, diagnostics := o.lowerBlock(ctx, typed)
|
|
2842
|
-
return
|
|
3205
|
+
return append(out, loweredStmt{hasBlock: true, children: body}), diagnostics
|
|
2843
3206
|
case *ast.AssignStmt:
|
|
2844
|
-
|
|
3207
|
+
stmts, diagnostics := o.lowerAssignStmt(ctx, typed)
|
|
3208
|
+
return append(out, stmts...), diagnostics
|
|
2845
3209
|
case *ast.SendStmt:
|
|
2846
3210
|
text, diagnostics := o.lowerSendStmt(ctx, typed)
|
|
2847
|
-
return
|
|
3211
|
+
return append(out, loweredStmt{text: text}), diagnostics
|
|
2848
3212
|
case *ast.GoStmt:
|
|
2849
3213
|
text, diagnostics := o.lowerGoStmt(ctx, typed)
|
|
2850
|
-
return
|
|
3214
|
+
return append(out, loweredStmt{text: text}), diagnostics
|
|
2851
3215
|
case *ast.DeferStmt:
|
|
2852
3216
|
text, diagnostics := o.lowerDeferStmt(ctx, typed)
|
|
2853
|
-
return
|
|
3217
|
+
return append(out, loweredStmt{text: text}), diagnostics
|
|
2854
3218
|
case *ast.ExprStmt:
|
|
2855
3219
|
text, diagnostics := o.lowerExpr(ctx, typed.X)
|
|
2856
|
-
return
|
|
3220
|
+
return append(out, loweredStmt{text: expressionStmtText(text)}), diagnostics
|
|
2857
3221
|
case *ast.ReturnStmt:
|
|
2858
3222
|
text, diagnostics := o.lowerReturnStmt(ctx, typed)
|
|
2859
|
-
return
|
|
3223
|
+
return append(out, loweredStmt{text: text}), diagnostics
|
|
2860
3224
|
case *ast.IfStmt:
|
|
2861
3225
|
var diagnostics []Diagnostic
|
|
2862
3226
|
var init []loweredStmt
|
|
@@ -2889,39 +3253,43 @@ func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
2889
3253
|
}
|
|
2890
3254
|
if len(init) != 0 {
|
|
2891
3255
|
init = append(init, stmt)
|
|
2892
|
-
|
|
3256
|
+
initPrelude = append(initPrelude, loweredStmt{children: init})
|
|
3257
|
+
return append(out, initPrelude...), diagnostics
|
|
2893
3258
|
}
|
|
2894
|
-
return
|
|
3259
|
+
return append(out, stmt), diagnostics
|
|
2895
3260
|
case *ast.ForStmt:
|
|
2896
3261
|
lowered, diagnostics := o.lowerForStmt(ctx, typed)
|
|
2897
|
-
return
|
|
3262
|
+
return append(out, lowered), diagnostics
|
|
2898
3263
|
case *ast.RangeStmt:
|
|
2899
3264
|
lowered, diagnostics := o.lowerRangeStmt(ctx, typed)
|
|
2900
|
-
return
|
|
3265
|
+
return append(out, lowered), diagnostics
|
|
2901
3266
|
case *ast.SelectStmt:
|
|
2902
3267
|
lowered, diagnostics := o.lowerSelectStmt(ctx, typed)
|
|
2903
|
-
return
|
|
3268
|
+
return append(out, loweredStmt{selectStmt: lowered}), diagnostics
|
|
2904
3269
|
case *ast.SwitchStmt:
|
|
2905
|
-
|
|
3270
|
+
stmts, diagnostics := o.lowerSwitchStmt(ctx, typed)
|
|
3271
|
+
return append(out, stmts...), diagnostics
|
|
2906
3272
|
case *ast.TypeSwitchStmt:
|
|
2907
|
-
|
|
3273
|
+
stmts, diagnostics := o.lowerTypeSwitchStmt(ctx, typed)
|
|
3274
|
+
return append(out, stmts...), diagnostics
|
|
2908
3275
|
case *ast.LabeledStmt:
|
|
2909
3276
|
lowered, diagnostics := o.lowerStmt(ctx, typed.Stmt)
|
|
2910
3277
|
if len(lowered) != 0 {
|
|
2911
3278
|
label := safeIdentifier(typed.Label.Name)
|
|
2912
3279
|
if lowered[0].text == "" {
|
|
2913
|
-
return
|
|
3280
|
+
return append(out, loweredStmt{text: label + ":", children: lowered}), diagnostics
|
|
2914
3281
|
}
|
|
2915
3282
|
if labeledTextCannotPrefix(lowered[0].text) {
|
|
2916
|
-
|
|
3283
|
+
out = append(out, loweredStmt{text: label + ":;"})
|
|
3284
|
+
return append(out, lowered...), diagnostics
|
|
2917
3285
|
}
|
|
2918
3286
|
lowered[0].text = label + ": " + lowered[0].text
|
|
2919
3287
|
}
|
|
2920
|
-
return lowered, diagnostics
|
|
3288
|
+
return append(out, lowered...), diagnostics
|
|
2921
3289
|
case *ast.IncDecStmt:
|
|
2922
3290
|
if star, ok := unwrapParenExpr(typed.X).(*ast.StarExpr); ok {
|
|
2923
3291
|
expr, diagnostics := o.lowerPointerStorageExpr(ctx, star.X)
|
|
2924
|
-
return
|
|
3292
|
+
return append(out, loweredStmt{text: expr + typed.Tok.String()}), diagnostics
|
|
2925
3293
|
}
|
|
2926
3294
|
if index, ok := unwrapParenExpr(typed.X).(*ast.IndexExpr); ok && isMapType(ctx.semPkg.source.TypesInfo.TypeOf(index.X)) {
|
|
2927
3295
|
right := "1"
|
|
@@ -2929,7 +3297,8 @@ func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
2929
3297
|
if typed.Tok == token.DEC {
|
|
2930
3298
|
tok = token.SUB_ASSIGN
|
|
2931
3299
|
}
|
|
2932
|
-
|
|
3300
|
+
stmts, diagnostics := o.lowerMapIndexUpdateStmts(ctx, index, tok, right, ctx.semPkg.source.TypesInfo.TypeOf(typed.X))
|
|
3301
|
+
return append(out, stmts...), diagnostics
|
|
2933
3302
|
}
|
|
2934
3303
|
if setter, ok := o.packageVarSetterForAssignment(ctx, typed.X); ok {
|
|
2935
3304
|
expr, diagnostics := o.lowerExpr(ctx, typed.X)
|
|
@@ -2937,58 +3306,58 @@ func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
2937
3306
|
if typed.Tok == token.DEC {
|
|
2938
3307
|
op = "-"
|
|
2939
3308
|
}
|
|
2940
|
-
return
|
|
3309
|
+
return append(out, loweredStmt{text: setter + "(" + expr + " " + op + " 1)"}), diagnostics
|
|
2941
3310
|
}
|
|
2942
3311
|
expr, diagnostics := o.lowerExpr(ctx, typed.X)
|
|
2943
|
-
return
|
|
3312
|
+
return append(out, loweredStmt{text: expr + typed.Tok.String()}), diagnostics
|
|
2944
3313
|
case *ast.BranchStmt:
|
|
2945
3314
|
if typed.Label != nil {
|
|
2946
3315
|
switch typed.Tok {
|
|
2947
3316
|
case token.BREAK, token.CONTINUE:
|
|
2948
|
-
return
|
|
3317
|
+
return append(out, loweredStmt{text: typed.Tok.String() + " " + safeIdentifier(typed.Label.Name)}), nil
|
|
2949
3318
|
case token.GOTO:
|
|
2950
3319
|
label := safeIdentifier(typed.Label.Name)
|
|
2951
3320
|
if ctx.gotoStateLabels[label] {
|
|
2952
|
-
return
|
|
2953
|
-
{text: ctx.gotoStateVar + " = " + strconv.Quote(label)},
|
|
2954
|
-
{text: "continue " + ctx.gotoStateLoop},
|
|
2955
|
-
|
|
3321
|
+
return append(out,
|
|
3322
|
+
loweredStmt{text: ctx.gotoStateVar + " = " + strconv.Quote(label)},
|
|
3323
|
+
loweredStmt{text: "continue " + ctx.gotoStateLoop},
|
|
3324
|
+
), nil
|
|
2956
3325
|
}
|
|
2957
3326
|
if ctx.forwardGotos[label] {
|
|
2958
|
-
return
|
|
3327
|
+
return append(out, loweredStmt{text: "break " + label}), nil
|
|
2959
3328
|
}
|
|
2960
3329
|
if ctx.gotoLabels[label] {
|
|
2961
|
-
return
|
|
3330
|
+
return append(out, loweredStmt{text: "continue " + label}), nil
|
|
2962
3331
|
}
|
|
2963
|
-
return
|
|
3332
|
+
return out, []Diagnostic{loweringUnsupported("statement", ctx.semPkg.pkgPath, "unsupported goto branch to "+label)}
|
|
2964
3333
|
default:
|
|
2965
|
-
return
|
|
3334
|
+
return out, []Diagnostic{loweringUnsupported("statement", ctx.semPkg.pkgPath, "unsupported labeled branch")}
|
|
2966
3335
|
}
|
|
2967
3336
|
}
|
|
2968
3337
|
switch typed.Tok {
|
|
2969
3338
|
case token.BREAK, token.CONTINUE:
|
|
2970
3339
|
if typed.Tok == token.BREAK && ctx.loopLabel != "" && !ctx.switchBreak {
|
|
2971
|
-
return
|
|
3340
|
+
return append(out, loweredStmt{text: "break " + ctx.loopLabel}), nil
|
|
2972
3341
|
}
|
|
2973
3342
|
if typed.Tok == token.CONTINUE && ctx.loopLabel != "" {
|
|
2974
|
-
return
|
|
3343
|
+
return append(out, loweredStmt{text: "continue " + ctx.loopLabel}), nil
|
|
2975
3344
|
}
|
|
2976
3345
|
if typed.Tok == token.BREAK && ctx.rangeBranch != nil && ctx.rangeBreak {
|
|
2977
|
-
return
|
|
3346
|
+
return append(out, loweredStmt{text: "return false"}), nil
|
|
2978
3347
|
}
|
|
2979
3348
|
if typed.Tok == token.CONTINUE && ctx.rangeBranch != nil && ctx.rangeContinue {
|
|
2980
|
-
return
|
|
3349
|
+
return append(out, loweredStmt{text: "return true"}), nil
|
|
2981
3350
|
}
|
|
2982
|
-
return
|
|
3351
|
+
return append(out, loweredStmt{text: typed.Tok.String()}), nil
|
|
2983
3352
|
case token.FALLTHROUGH:
|
|
2984
|
-
return
|
|
3353
|
+
return append(out, loweredStmt{text: "fallthrough"}), nil
|
|
2985
3354
|
default:
|
|
2986
|
-
return
|
|
3355
|
+
return out, []Diagnostic{loweringUnsupported("statement", ctx.semPkg.pkgPath, "unsupported branch")}
|
|
2987
3356
|
}
|
|
2988
3357
|
case *ast.EmptyStmt:
|
|
2989
|
-
return
|
|
3358
|
+
return out, nil
|
|
2990
3359
|
default:
|
|
2991
|
-
return
|
|
3360
|
+
return out, []Diagnostic{loweringUnsupported("statement", ctx.semPkg.pkgPath, "unsupported statement kind")}
|
|
2992
3361
|
}
|
|
2993
3362
|
}
|
|
2994
3363
|
|
|
@@ -3034,113 +3403,122 @@ func (o *LoweringOwner) lowerStmtListAfter(
|
|
|
3034
3403
|
) ([]loweredStmt, []Diagnostic) {
|
|
3035
3404
|
lowered := make([]loweredStmt, 0, len(stmts))
|
|
3036
3405
|
var diagnostics []Diagnostic
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
group.
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3406
|
+
hasGoto := stmtListHasGoto(stmts)
|
|
3407
|
+
var gotoSpans map[string]int
|
|
3408
|
+
var gotoLabels map[string]bool
|
|
3409
|
+
var forwardStarts map[int]forwardGotoLabelSpan
|
|
3410
|
+
if hasGoto {
|
|
3411
|
+
gotoSpans = backwardGotoLabelSpans(stmts)
|
|
3412
|
+
gotoLabels = make(map[string]bool, len(gotoSpans))
|
|
3413
|
+
for label := range gotoSpans {
|
|
3414
|
+
gotoLabels[label] = true
|
|
3415
|
+
}
|
|
3416
|
+
forwardSpans := forwardGotoLabelSpans(stmts, gotoSpans)
|
|
3417
|
+
forwardStarts = make(map[int]forwardGotoLabelSpan, len(forwardSpans))
|
|
3418
|
+
for label, span := range forwardSpans {
|
|
3419
|
+
span.label = label
|
|
3420
|
+
group := forwardStarts[span.start]
|
|
3421
|
+
if group.forwardLabels == nil {
|
|
3422
|
+
group.forwardLabels = make(map[string]bool)
|
|
3423
|
+
}
|
|
3424
|
+
group.forwardLabels[label] = true
|
|
3425
|
+
if group.label == "" || span.labelIdx > group.labelIdx {
|
|
3426
|
+
group.label = span.label
|
|
3427
|
+
group.start = span.start
|
|
3428
|
+
group.labelIdx = span.labelIdx
|
|
3429
|
+
}
|
|
3430
|
+
forwardStarts[span.start] = group
|
|
3431
|
+
}
|
|
3057
3432
|
}
|
|
3058
3433
|
for idx := 0; idx < len(stmts); idx++ {
|
|
3059
3434
|
stmt := stmts[idx]
|
|
3060
3435
|
startLine := sourceLine(ctx, stmt.Pos())
|
|
3061
3436
|
leading := leadingStmtLines(ctx, prevEndLine, startLine)
|
|
3062
|
-
if
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
}
|
|
3069
|
-
idx = cluster.endIdx
|
|
3070
|
-
continue
|
|
3071
|
-
}
|
|
3072
|
-
if span, ok := leadingGotoBackwardLoopSpan(stmts, idx, gotoSpans); ok {
|
|
3073
|
-
loop, loopDiagnostics := o.lowerBackwardGotoLoop(
|
|
3074
|
-
ctx,
|
|
3075
|
-
gotoLabels,
|
|
3076
|
-
span.label,
|
|
3077
|
-
span.labelIdx,
|
|
3078
|
-
span.endIdx,
|
|
3079
|
-
span.forwardLabel,
|
|
3080
|
-
stmts,
|
|
3081
|
-
leading,
|
|
3082
|
-
)
|
|
3083
|
-
diagnostics = append(diagnostics, loopDiagnostics...)
|
|
3084
|
-
lowered = append(lowered, loop...)
|
|
3085
|
-
if endLine := sourceLine(ctx, stmts[span.endIdx].End()); endLine != 0 {
|
|
3086
|
-
prevEndLine = endLine
|
|
3087
|
-
}
|
|
3088
|
-
idx = span.endIdx
|
|
3089
|
-
continue
|
|
3090
|
-
}
|
|
3091
|
-
if span, ok := forwardStarts[idx]; ok {
|
|
3092
|
-
bodyStmts := stmts[idx:span.labelIdx]
|
|
3093
|
-
body, bodyDiagnostics := o.lowerStmtListAfter(
|
|
3094
|
-
ctx.withForwardGotos(span.forwardLabels),
|
|
3095
|
-
bodyStmts,
|
|
3096
|
-
prevEndLine,
|
|
3097
|
-
)
|
|
3098
|
-
diagnostics = append(diagnostics, bodyDiagnostics...)
|
|
3099
|
-
block := loweredStmt{hasBlock: true, text: span.label + ":", children: body}
|
|
3100
|
-
if len(leading) != 0 {
|
|
3101
|
-
block.leading = append(leading, block.leading...)
|
|
3102
|
-
}
|
|
3103
|
-
lowered = append(lowered, block)
|
|
3104
|
-
if labeled, ok := stmts[span.labelIdx].(*ast.LabeledStmt); ok {
|
|
3105
|
-
labelLowered, labelDiagnostics := o.lowerStmt(ctx, labeled.Stmt)
|
|
3106
|
-
diagnostics = append(diagnostics, labelDiagnostics...)
|
|
3107
|
-
lowered = append(lowered, labelLowered...)
|
|
3108
|
-
if endLine := sourceLine(ctx, labeled.End()); endLine != 0 {
|
|
3437
|
+
if hasGoto {
|
|
3438
|
+
if cluster, ok := gotoStateClusterAt(stmts, idx); ok {
|
|
3439
|
+
clusterLowered, clusterDiagnostics := o.lowerGotoStateCluster(ctx, stmts, cluster, leading)
|
|
3440
|
+
diagnostics = append(diagnostics, clusterDiagnostics...)
|
|
3441
|
+
lowered = append(lowered, clusterLowered...)
|
|
3442
|
+
if endLine := sourceLine(ctx, stmts[cluster.endIdx].End()); endLine != 0 {
|
|
3109
3443
|
prevEndLine = endLine
|
|
3110
3444
|
}
|
|
3445
|
+
idx = cluster.endIdx
|
|
3446
|
+
continue
|
|
3111
3447
|
}
|
|
3112
|
-
idx
|
|
3113
|
-
continue
|
|
3114
|
-
}
|
|
3115
|
-
if labeled, ok := stmt.(*ast.LabeledStmt); ok {
|
|
3116
|
-
label := safeIdentifier(labeled.Label.Name)
|
|
3117
|
-
if endIdx, ok := gotoSpans[label]; ok {
|
|
3448
|
+
if span, ok := leadingGotoBackwardLoopSpan(stmts, idx, gotoSpans); ok {
|
|
3118
3449
|
loop, loopDiagnostics := o.lowerBackwardGotoLoop(
|
|
3119
3450
|
ctx,
|
|
3120
3451
|
gotoLabels,
|
|
3121
|
-
label,
|
|
3122
|
-
|
|
3123
|
-
endIdx,
|
|
3124
|
-
|
|
3452
|
+
span.label,
|
|
3453
|
+
span.labelIdx,
|
|
3454
|
+
span.endIdx,
|
|
3455
|
+
span.forwardLabel,
|
|
3125
3456
|
stmts,
|
|
3126
3457
|
leading,
|
|
3127
3458
|
)
|
|
3128
3459
|
diagnostics = append(diagnostics, loopDiagnostics...)
|
|
3129
3460
|
lowered = append(lowered, loop...)
|
|
3130
|
-
if endLine := sourceLine(ctx, stmts[endIdx].End()); endLine != 0 {
|
|
3461
|
+
if endLine := sourceLine(ctx, stmts[span.endIdx].End()); endLine != 0 {
|
|
3131
3462
|
prevEndLine = endLine
|
|
3132
3463
|
}
|
|
3133
|
-
idx = endIdx
|
|
3464
|
+
idx = span.endIdx
|
|
3465
|
+
continue
|
|
3466
|
+
}
|
|
3467
|
+
if span, ok := forwardStarts[idx]; ok {
|
|
3468
|
+
bodyStmts := stmts[idx:span.labelIdx]
|
|
3469
|
+
body, bodyDiagnostics := o.lowerStmtListAfter(
|
|
3470
|
+
ctx.withForwardGotos(span.forwardLabels),
|
|
3471
|
+
bodyStmts,
|
|
3472
|
+
prevEndLine,
|
|
3473
|
+
)
|
|
3474
|
+
diagnostics = append(diagnostics, bodyDiagnostics...)
|
|
3475
|
+
block := loweredStmt{hasBlock: true, text: span.label + ":", children: body}
|
|
3476
|
+
if len(leading) != 0 {
|
|
3477
|
+
block.leading = append(leading, block.leading...)
|
|
3478
|
+
}
|
|
3479
|
+
lowered = append(lowered, block)
|
|
3480
|
+
if labeled, ok := stmts[span.labelIdx].(*ast.LabeledStmt); ok {
|
|
3481
|
+
labelLowered, labelDiagnostics := o.lowerStmt(ctx, labeled.Stmt)
|
|
3482
|
+
diagnostics = append(diagnostics, labelDiagnostics...)
|
|
3483
|
+
lowered = append(lowered, labelLowered...)
|
|
3484
|
+
if endLine := sourceLine(ctx, labeled.End()); endLine != 0 {
|
|
3485
|
+
prevEndLine = endLine
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
idx = span.labelIdx
|
|
3134
3489
|
continue
|
|
3135
3490
|
}
|
|
3491
|
+
if labeled, ok := stmt.(*ast.LabeledStmt); ok {
|
|
3492
|
+
label := safeIdentifier(labeled.Label.Name)
|
|
3493
|
+
if endIdx, ok := gotoSpans[label]; ok {
|
|
3494
|
+
loop, loopDiagnostics := o.lowerBackwardGotoLoop(
|
|
3495
|
+
ctx,
|
|
3496
|
+
gotoLabels,
|
|
3497
|
+
label,
|
|
3498
|
+
idx,
|
|
3499
|
+
endIdx,
|
|
3500
|
+
"",
|
|
3501
|
+
stmts,
|
|
3502
|
+
leading,
|
|
3503
|
+
)
|
|
3504
|
+
diagnostics = append(diagnostics, loopDiagnostics...)
|
|
3505
|
+
lowered = append(lowered, loop...)
|
|
3506
|
+
if endLine := sourceLine(ctx, stmts[endIdx].End()); endLine != 0 {
|
|
3507
|
+
prevEndLine = endLine
|
|
3508
|
+
}
|
|
3509
|
+
idx = endIdx
|
|
3510
|
+
continue
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3136
3513
|
}
|
|
3137
3514
|
if stmtCtx, nextCtx, ok := o.lowerDeclStatementContext(ctx, stmt); ok {
|
|
3138
|
-
|
|
3515
|
+
start := len(lowered)
|
|
3516
|
+
var stmtDiagnostics []Diagnostic
|
|
3517
|
+
lowered, stmtDiagnostics = o.lowerStmtInto(stmtCtx, stmt, lowered)
|
|
3139
3518
|
diagnostics = append(diagnostics, stmtDiagnostics...)
|
|
3140
|
-
if len(
|
|
3141
|
-
|
|
3519
|
+
if len(lowered) > start && len(leading) != 0 {
|
|
3520
|
+
lowered[start].leading = append(leading, lowered[start].leading...)
|
|
3142
3521
|
}
|
|
3143
|
-
lowered = append(lowered, stmtLowered...)
|
|
3144
3522
|
ctx = nextCtx
|
|
3145
3523
|
if endLine := sourceLine(ctx, stmt.End()); endLine != 0 {
|
|
3146
3524
|
prevEndLine = endLine
|
|
@@ -3165,12 +3543,13 @@ func (o *LoweringOwner) lowerStmtListAfter(
|
|
|
3165
3543
|
}
|
|
3166
3544
|
continue
|
|
3167
3545
|
}
|
|
3168
|
-
|
|
3546
|
+
start := len(lowered)
|
|
3547
|
+
var stmtDiagnostics []Diagnostic
|
|
3548
|
+
lowered, stmtDiagnostics = o.lowerStmtInto(ctx, stmt, lowered)
|
|
3169
3549
|
diagnostics = append(diagnostics, stmtDiagnostics...)
|
|
3170
|
-
if len(
|
|
3171
|
-
|
|
3550
|
+
if len(lowered) > start && len(leading) != 0 {
|
|
3551
|
+
lowered[start].leading = append(leading, lowered[start].leading...)
|
|
3172
3552
|
}
|
|
3173
|
-
lowered = append(lowered, stmtLowered...)
|
|
3174
3553
|
if endLine := sourceLine(ctx, stmt.End()); endLine != 0 {
|
|
3175
3554
|
prevEndLine = endLine
|
|
3176
3555
|
}
|
|
@@ -3204,7 +3583,7 @@ func (o *LoweringOwner) lowerDeclStatementContext(
|
|
|
3204
3583
|
if def == nil || aliases[def] != "" {
|
|
3205
3584
|
continue
|
|
3206
3585
|
}
|
|
3207
|
-
if shortDeclDefShadowsOuterName(name.Name, def) {
|
|
3586
|
+
if shortDeclDefShadowsOuterName(ctx, name.Name, def) || valueSpecUsesOuterName(ctx, valueSpec, name.Name, def) {
|
|
3208
3587
|
aliases[def] = ctx.tempName("Shadow")
|
|
3209
3588
|
}
|
|
3210
3589
|
}
|
|
@@ -3308,7 +3687,7 @@ func (o *LoweringOwner) lowerGotoStateCluster(
|
|
|
3308
3687
|
for _, label := range cluster.labels {
|
|
3309
3688
|
labels[label.name] = true
|
|
3310
3689
|
}
|
|
3311
|
-
stateCtx := ctx.withGotoState(labels, stateVar, loopLabel)
|
|
3690
|
+
stateCtx := ctx.withGotoState(labels, stateVar, loopLabel).withFunctionScopedDecls()
|
|
3312
3691
|
|
|
3313
3692
|
var diagnostics []Diagnostic
|
|
3314
3693
|
initialState := cluster.labels[0].name
|
|
@@ -3404,7 +3783,7 @@ func (o *LoweringOwner) lowerBackwardGotoLoop(
|
|
|
3404
3783
|
var lowered []loweredStmt
|
|
3405
3784
|
var body []loweredStmt
|
|
3406
3785
|
var diagnostics []Diagnostic
|
|
3407
|
-
bodyCtx := ctx.withGotoLabels(gotoLabels)
|
|
3786
|
+
bodyCtx := ctx.withGotoLabels(gotoLabels).withFunctionScopedDecls()
|
|
3408
3787
|
if initialForwardLabel != "" {
|
|
3409
3788
|
skipVar := ctx.tempName("Skip")
|
|
3410
3789
|
init := loweredStmt{text: "let " + skipVar + " = true"}
|
|
@@ -3452,9 +3831,30 @@ type leadingGotoBackwardLoop struct {
|
|
|
3452
3831
|
}
|
|
3453
3832
|
|
|
3454
3833
|
func stmtListNeedsLoopBranchLabel(stmts []ast.Stmt) bool {
|
|
3834
|
+
if !stmtListHasGoto(stmts) {
|
|
3835
|
+
return false
|
|
3836
|
+
}
|
|
3455
3837
|
return len(backwardGotoLabelSpans(stmts)) != 0
|
|
3456
3838
|
}
|
|
3457
3839
|
|
|
3840
|
+
func stmtListHasGoto(stmts []ast.Stmt) bool {
|
|
3841
|
+
for _, stmt := range stmts {
|
|
3842
|
+
hasGoto := false
|
|
3843
|
+
ast.Inspect(stmt, func(node ast.Node) bool {
|
|
3844
|
+
branch, ok := node.(*ast.BranchStmt)
|
|
3845
|
+
if ok && branch.Tok == token.GOTO && branch.Label != nil {
|
|
3846
|
+
hasGoto = true
|
|
3847
|
+
return false
|
|
3848
|
+
}
|
|
3849
|
+
return !hasGoto
|
|
3850
|
+
})
|
|
3851
|
+
if hasGoto {
|
|
3852
|
+
return true
|
|
3853
|
+
}
|
|
3854
|
+
}
|
|
3855
|
+
return false
|
|
3856
|
+
}
|
|
3857
|
+
|
|
3458
3858
|
func backwardGotoLabelSpans(stmts []ast.Stmt) map[string]int {
|
|
3459
3859
|
seenLabels := make(map[string]bool)
|
|
3460
3860
|
spans := make(map[string]int)
|
|
@@ -3673,7 +4073,7 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
3673
4073
|
}
|
|
3674
4074
|
prefix := ""
|
|
3675
4075
|
if stmt.Tok == token.DEFINE {
|
|
3676
|
-
prefix =
|
|
4076
|
+
prefix = declarationKeyword(ctx)
|
|
3677
4077
|
if !allShortAssignTargetsNew(ctx, stmt.Lhs) || o.tupleDeclarationNeedsElementStatements(ctx, stmt) {
|
|
3678
4078
|
return o.lowerTupleReassignmentStmt(ctx, stmt, right, diagnostics)
|
|
3679
4079
|
}
|
|
@@ -3734,26 +4134,18 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
3734
4134
|
if starTarget && stmt.Tok != token.DEFINE {
|
|
3735
4135
|
pointer, pointerDiagnostics := o.lowerPointerStorageExpr(ctx, star.X)
|
|
3736
4136
|
diagnostics = append(diagnostics, pointerDiagnostics...)
|
|
3737
|
-
if stmt.Tok == token.AND_NOT_ASSIGN {
|
|
3738
|
-
stmts = append(stmts, loweredStmt{text: pointer + " = " + pointer + " & ~(" + right + ")"})
|
|
3739
|
-
continue
|
|
3740
|
-
}
|
|
3741
4137
|
if value, ok := integerQuotientAssignExpr(targetType, pointer, right, stmt.Tok); ok {
|
|
3742
4138
|
stmts = append(stmts, loweredStmt{text: value})
|
|
3743
4139
|
continue
|
|
3744
4140
|
}
|
|
3745
|
-
stmts = append(stmts, loweredStmt{text: pointer + " " +
|
|
4141
|
+
stmts = append(stmts, loweredStmt{text: pointer + " = " + lowerCompoundAssignValue(o.runtimeOwner, targetType, pointer, right, stmt.Tok)})
|
|
3746
4142
|
continue
|
|
3747
4143
|
}
|
|
3748
4144
|
if isShortDecl {
|
|
3749
4145
|
if ident, ok := lhs.(*ast.Ident); ok {
|
|
3750
4146
|
right = o.lowerDeclaredValue(ctx, ident, right)
|
|
3751
4147
|
}
|
|
3752
|
-
stmts = append(stmts, loweredStmt{text:
|
|
3753
|
-
continue
|
|
3754
|
-
}
|
|
3755
|
-
if stmt.Tok == token.AND_NOT_ASSIGN {
|
|
3756
|
-
stmts = append(stmts, loweredStmt{text: left + " = " + left + " & ~(" + right + ")"})
|
|
4148
|
+
stmts = append(stmts, loweredStmt{text: declarationKeyword(ctx) + left + o.shortDeclTypeAnnotation(ctx, lhs, stmt.Rhs[idx]) + " = " + right})
|
|
3757
4149
|
continue
|
|
3758
4150
|
}
|
|
3759
4151
|
if helper, ok := wideIntegerAssignHelper(targetType, stmt.Tok); ok {
|
|
@@ -3768,6 +4160,10 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
3768
4160
|
if stmt.Tok == token.DEFINE {
|
|
3769
4161
|
op = "="
|
|
3770
4162
|
}
|
|
4163
|
+
if stmt.Tok != token.ASSIGN && stmt.Tok != token.DEFINE {
|
|
4164
|
+
stmts = append(stmts, loweredStmt{text: left + " = " + lowerCompoundAssignValue(o.runtimeOwner, targetType, left, right, stmt.Tok)})
|
|
4165
|
+
continue
|
|
4166
|
+
}
|
|
3771
4167
|
stmts = append(stmts, loweredStmt{text: left + " " + op + " " + right})
|
|
3772
4168
|
}
|
|
3773
4169
|
return stmts, diagnostics
|
|
@@ -3810,6 +4206,7 @@ func lowerCompoundAssignValue(
|
|
|
3810
4206
|
if value, ok := integerQuotientAssignValueExpr(targetType, left, right, tok); ok {
|
|
3811
4207
|
return value
|
|
3812
4208
|
}
|
|
4209
|
+
right = "(" + right + ")"
|
|
3813
4210
|
switch tok {
|
|
3814
4211
|
case token.ADD_ASSIGN:
|
|
3815
4212
|
return left + " + " + right
|
|
@@ -3830,6 +4227,9 @@ func lowerCompoundAssignValue(
|
|
|
3830
4227
|
case token.SHL_ASSIGN:
|
|
3831
4228
|
return left + " << " + right
|
|
3832
4229
|
case token.SHR_ASSIGN:
|
|
4230
|
+
if bits, ok := unsignedIntegerBits(targetType); ok && bits <= 32 {
|
|
4231
|
+
return "(" + left + " >>> " + right + ") >>> 0"
|
|
4232
|
+
}
|
|
3833
4233
|
return left + " >> " + right
|
|
3834
4234
|
case token.AND_NOT_ASSIGN:
|
|
3835
4235
|
return left + " & ~(" + right + ")"
|
|
@@ -3866,30 +4266,31 @@ func integerQuotientAssignValueExpr(targetType types.Type, left string, right st
|
|
|
3866
4266
|
}
|
|
3867
4267
|
|
|
3868
4268
|
func wideIntegerAssignHelper(targetType types.Type, tok token.Token) (RuntimeHelper, bool) {
|
|
3869
|
-
if !
|
|
4269
|
+
if !isRuntimeWideIntegerType(targetType) {
|
|
3870
4270
|
return "", false
|
|
3871
4271
|
}
|
|
4272
|
+
signed := isFixedSignedWideIntegerType(targetType)
|
|
3872
4273
|
switch tok {
|
|
3873
4274
|
case token.SHL_ASSIGN:
|
|
3874
|
-
return RuntimeHelperUint64Shl, true
|
|
4275
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Shl, RuntimeHelperInt64Shl), true
|
|
3875
4276
|
case token.SHR_ASSIGN:
|
|
3876
|
-
return RuntimeHelperUint64Shr, true
|
|
4277
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Shr, RuntimeHelperInt64Shr), true
|
|
3877
4278
|
case token.MUL_ASSIGN:
|
|
3878
|
-
return wideIntegerHelper(
|
|
4279
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Mul, RuntimeHelperInt64Mul), true
|
|
3879
4280
|
case token.QUO_ASSIGN:
|
|
3880
|
-
return wideIntegerHelper(
|
|
4281
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Div, RuntimeHelperInt64Div), true
|
|
3881
4282
|
case token.REM_ASSIGN:
|
|
3882
|
-
return wideIntegerHelper(
|
|
4283
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Mod, RuntimeHelperInt64Mod), true
|
|
3883
4284
|
case token.ADD_ASSIGN:
|
|
3884
|
-
return wideIntegerHelper(
|
|
4285
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Add, RuntimeHelperInt64Add), true
|
|
3885
4286
|
case token.SUB_ASSIGN:
|
|
3886
|
-
return wideIntegerHelper(
|
|
4287
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Sub, RuntimeHelperInt64Sub), true
|
|
3887
4288
|
case token.AND_ASSIGN:
|
|
3888
|
-
return wideIntegerHelper(
|
|
4289
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64And, RuntimeHelperInt64And), true
|
|
3889
4290
|
case token.OR_ASSIGN:
|
|
3890
|
-
return wideIntegerHelper(
|
|
4291
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Or, RuntimeHelperInt64Or), true
|
|
3891
4292
|
case token.XOR_ASSIGN:
|
|
3892
|
-
return wideIntegerHelper(
|
|
4293
|
+
return wideIntegerHelper(signed, RuntimeHelperUint64Xor, RuntimeHelperInt64Xor), true
|
|
3893
4294
|
default:
|
|
3894
4295
|
return "", false
|
|
3895
4296
|
}
|
|
@@ -3922,7 +4323,7 @@ func (o *LoweringOwner) lowerChannelReceiveAssignStmt(
|
|
|
3922
4323
|
diagnostics = append(diagnostics, leftDiagnostics...)
|
|
3923
4324
|
prefix := ""
|
|
3924
4325
|
if stmt.Tok == token.DEFINE {
|
|
3925
|
-
prefix =
|
|
4326
|
+
prefix = declarationKeyword(ctx)
|
|
3926
4327
|
left += o.shortDeclTypeAnnotation(ctx, stmt.Lhs[0], nil)
|
|
3927
4328
|
value = o.lowerDeclaredValue(ctx, stmt.Lhs[0], value)
|
|
3928
4329
|
}
|
|
@@ -3983,7 +4384,8 @@ func isIdentLikeExpr(expr ast.Expr) bool {
|
|
|
3983
4384
|
func shortDeclNeedsTypeAnnotation(typ types.Type) bool {
|
|
3984
4385
|
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
3985
4386
|
case *types.Pointer:
|
|
3986
|
-
|
|
4387
|
+
_, pointsToArray := types.Unalias(typed.Elem()).Underlying().(*types.Array)
|
|
4388
|
+
return pointsToArray || namedStructType(typed.Elem()) != nil || namedNonStructType(typed.Elem()) != nil
|
|
3987
4389
|
case *types.Map:
|
|
3988
4390
|
return true
|
|
3989
4391
|
case *types.Slice:
|
|
@@ -4025,7 +4427,7 @@ func (o *LoweringOwner) lowerTupleTargetAssignmentStmt(
|
|
|
4025
4427
|
left, diagnostics := o.lowerAssignmentTarget(ctx, lhs, declare)
|
|
4026
4428
|
prefix := ""
|
|
4027
4429
|
if declare {
|
|
4028
|
-
prefix =
|
|
4430
|
+
prefix = declarationKeyword(ctx)
|
|
4029
4431
|
left += o.shortDeclTypeAnnotation(ctx, lhs, nil)
|
|
4030
4432
|
value = o.lowerDeclaredValue(ctx, lhs, value)
|
|
4031
4433
|
}
|
|
@@ -4172,7 +4574,7 @@ func (o *LoweringOwner) lowerShortDeclNewShadowAliases(
|
|
|
4172
4574
|
if entry.def == nil || aliases[entry.def] != "" {
|
|
4173
4575
|
continue
|
|
4174
4576
|
}
|
|
4175
|
-
if shortDeclDefShadowsOuterName(entry.name, entry.def) {
|
|
4577
|
+
if shortDeclDefShadowsOuterName(ctx, entry.name, entry.def) {
|
|
4176
4578
|
aliases[entry.def] = ctx.tempName("Shadow")
|
|
4177
4579
|
}
|
|
4178
4580
|
}
|
|
@@ -4201,12 +4603,24 @@ func shortDeclShadowNonValueIdents(ctx lowerFileContext, expr ast.Expr) map[*ast
|
|
|
4201
4603
|
return idents
|
|
4202
4604
|
}
|
|
4203
4605
|
|
|
4204
|
-
func shortDeclDefShadowsOuterName(name string, def types.Object) bool {
|
|
4606
|
+
func shortDeclDefShadowsOuterName(ctx lowerFileContext, name string, def types.Object) bool {
|
|
4205
4607
|
for scope := def.Parent(); scope != nil; scope = scope.Parent() {
|
|
4206
4608
|
if scope == def.Parent() {
|
|
4207
4609
|
continue
|
|
4208
4610
|
}
|
|
4209
4611
|
obj := scope.Lookup(name)
|
|
4612
|
+
if scope.Parent() == types.Universe {
|
|
4613
|
+
if obj == nil {
|
|
4614
|
+
return false
|
|
4615
|
+
}
|
|
4616
|
+
if _, isTypeName := obj.(*types.TypeName); isTypeName {
|
|
4617
|
+
return true
|
|
4618
|
+
}
|
|
4619
|
+
if _, isFunc := obj.(*types.Func); isFunc {
|
|
4620
|
+
return sameSourceFile(ctx, obj.Pos(), def.Pos()) && obj.Pos() < def.Pos()
|
|
4621
|
+
}
|
|
4622
|
+
return false
|
|
4623
|
+
}
|
|
4210
4624
|
if obj != nil && obj.Pos().IsValid() && obj.Pos() < def.Pos() {
|
|
4211
4625
|
return true
|
|
4212
4626
|
}
|
|
@@ -4214,6 +4628,40 @@ func shortDeclDefShadowsOuterName(name string, def types.Object) bool {
|
|
|
4214
4628
|
return false
|
|
4215
4629
|
}
|
|
4216
4630
|
|
|
4631
|
+
func sameSourceFile(ctx lowerFileContext, left token.Pos, right token.Pos) bool {
|
|
4632
|
+
if !left.IsValid() || !right.IsValid() || ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
4633
|
+
return false
|
|
4634
|
+
}
|
|
4635
|
+
leftPos := sourcePos(ctx.semPkg.source, left)
|
|
4636
|
+
rightPos := sourcePos(ctx.semPkg.source, right)
|
|
4637
|
+
return leftPos.file != "" && leftPos.file == rightPos.file
|
|
4638
|
+
}
|
|
4639
|
+
|
|
4640
|
+
func valueSpecUsesOuterName(ctx lowerFileContext, spec *ast.ValueSpec, name string, def types.Object) bool {
|
|
4641
|
+
if spec == nil || name == "" || def == nil {
|
|
4642
|
+
return false
|
|
4643
|
+
}
|
|
4644
|
+
usesOuter := false
|
|
4645
|
+
for _, value := range spec.Values {
|
|
4646
|
+
ast.Inspect(value, func(node ast.Node) bool {
|
|
4647
|
+
ident, ok := node.(*ast.Ident)
|
|
4648
|
+
if !ok || ident.Name != name {
|
|
4649
|
+
return true
|
|
4650
|
+
}
|
|
4651
|
+
obj := ctx.semPkg.source.TypesInfo.Uses[ident]
|
|
4652
|
+
if obj != nil && obj != def {
|
|
4653
|
+
usesOuter = true
|
|
4654
|
+
return false
|
|
4655
|
+
}
|
|
4656
|
+
return true
|
|
4657
|
+
})
|
|
4658
|
+
if usesOuter {
|
|
4659
|
+
return true
|
|
4660
|
+
}
|
|
4661
|
+
}
|
|
4662
|
+
return false
|
|
4663
|
+
}
|
|
4664
|
+
|
|
4217
4665
|
func (o *LoweringOwner) mapIndexDefaultUsesShortDeclName(
|
|
4218
4666
|
ctx lowerFileContext,
|
|
4219
4667
|
rhs ast.Expr,
|
|
@@ -5273,7 +5721,7 @@ func (o *LoweringOwner) lowerRangeFuncStmt(
|
|
|
5273
5721
|
diagnostics = append(diagnostics, assignmentDiagnostics...)
|
|
5274
5722
|
body = append(assignments, body...)
|
|
5275
5723
|
}
|
|
5276
|
-
async := ctx.asyncFunction
|
|
5724
|
+
async := ctx.asyncFunction || stmtsContainAwait(body) || o.rangeFunctionValueNeedsAwait(ctx, stmt.X)
|
|
5277
5725
|
|
|
5278
5726
|
return loweredStmt{rangeFunc: &loweredRangeFunc{
|
|
5279
5727
|
value: rangeValue,
|
|
@@ -5902,6 +6350,19 @@ func (o *LoweringOwner) lowerComplexEqualityExpr(ctx lowerFileContext, expr *ast
|
|
|
5902
6350
|
return value, true
|
|
5903
6351
|
}
|
|
5904
6352
|
|
|
6353
|
+
func (o *LoweringOwner) lowerStructEqualityExpr(ctx lowerFileContext, expr *ast.BinaryExpr, left string, right string) (string, bool) {
|
|
6354
|
+
leftType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
6355
|
+
rightType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Y)
|
|
6356
|
+
if !isStructComparableType(leftType) || !isStructComparableType(rightType) {
|
|
6357
|
+
return "", false
|
|
6358
|
+
}
|
|
6359
|
+
value := o.runtimeOwner.QualifiedHelper(RuntimeHelperComparableEqual) + "(" + left + ", " + right + ")"
|
|
6360
|
+
if expr.Op == token.NEQ {
|
|
6361
|
+
value = "!" + value
|
|
6362
|
+
}
|
|
6363
|
+
return value, true
|
|
6364
|
+
}
|
|
6365
|
+
|
|
5905
6366
|
func (o *LoweringOwner) lowerStringEqualityExpr(ctx lowerFileContext, expr *ast.BinaryExpr, left string, right string) (string, bool) {
|
|
5906
6367
|
leftType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
5907
6368
|
rightType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Y)
|
|
@@ -6030,6 +6491,9 @@ func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
6030
6491
|
if value, ok := o.lowerComplexEqualityExpr(ctx, typed, left, right); ok {
|
|
6031
6492
|
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
6032
6493
|
}
|
|
6494
|
+
if value, ok := o.lowerStructEqualityExpr(ctx, typed, left, right); ok {
|
|
6495
|
+
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
6496
|
+
}
|
|
6033
6497
|
if value, ok := o.lowerStringEqualityExpr(ctx, typed, left, right); ok {
|
|
6034
6498
|
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
6035
6499
|
}
|
|
@@ -6073,6 +6537,10 @@ func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
6073
6537
|
return lowerPrefixUnaryExpr(typed.Op, value), diagnostics
|
|
6074
6538
|
}
|
|
6075
6539
|
if typed.Op == token.XOR {
|
|
6540
|
+
if bits, ok := unsignedIntegerBits(ctx.semPkg.source.TypesInfo.TypeOf(typed)); ok && bits <= 32 {
|
|
6541
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint) +
|
|
6542
|
+
"(~" + value + ", " + strconv.Itoa(bits) + ")", diagnostics
|
|
6543
|
+
}
|
|
6076
6544
|
return "~" + value, diagnostics
|
|
6077
6545
|
}
|
|
6078
6546
|
return value, append(diagnostics, loweringUnsupported("expression", ctx.semPkg.pkgPath, "unsupported unary operator"))
|
|
@@ -6155,7 +6623,7 @@ func isLegacyOctalLiteral(value string) bool {
|
|
|
6155
6623
|
func (o *LoweringOwner) lowerFuncLit(ctx lowerFileContext, lit *ast.FuncLit) (string, bool, []Diagnostic) {
|
|
6156
6624
|
signature, _ := ctx.semPkg.source.TypesInfo.TypeOf(lit).(*types.Signature)
|
|
6157
6625
|
deferState := &loweredDeferState{}
|
|
6158
|
-
bodyCtx := ctx.withSignature(signature).withDeferState(deferState).withoutRangeBranch()
|
|
6626
|
+
bodyCtx := ctx.withSignature(signature).withAsyncFunction(false).withDeferState(deferState).withoutRangeBranch()
|
|
6159
6627
|
asyncCompatibleParams := funcLiteralNeedsAsyncFunctionParamCalls(signature)
|
|
6160
6628
|
if asyncCompatibleParams || funcLiteralUsesFunctionIdentifierCall(ctx, lit) {
|
|
6161
6629
|
bodyCtx = bodyCtx.withAsyncFunction(true)
|
|
@@ -6276,7 +6744,7 @@ func (o *LoweringOwner) lowerIdent(ctx lowerFileContext, ident *ast.Ident, raw b
|
|
|
6276
6744
|
}
|
|
6277
6745
|
return alias
|
|
6278
6746
|
}
|
|
6279
|
-
if constObj, ok := obj.(*types.Const); ok &&
|
|
6747
|
+
if constObj, ok := obj.(*types.Const); ok && !raw {
|
|
6280
6748
|
if constValue, ok := lowerConstantValue(constObj.Val()); ok {
|
|
6281
6749
|
return constValue
|
|
6282
6750
|
}
|
|
@@ -6962,6 +7430,8 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
6962
7430
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperRunesToString) + "(" + value + ")", diagnostics
|
|
6963
7431
|
case isByteSliceType(sourceType):
|
|
6964
7432
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperBytesToString) + "(" + value + ")", diagnostics
|
|
7433
|
+
case overrideNamedStringType(ctx, o, sourceType):
|
|
7434
|
+
return "String(" + value + ")", diagnostics
|
|
6965
7435
|
case isStringType(sourceType):
|
|
6966
7436
|
return value, diagnostics
|
|
6967
7437
|
case isNumericType(sourceType):
|
|
@@ -7020,13 +7490,15 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
7020
7490
|
return renderNamedStructConversion(conversion), diagnostics
|
|
7021
7491
|
}
|
|
7022
7492
|
if isNumericType(targetType) {
|
|
7023
|
-
if constantValue, ok :=
|
|
7493
|
+
if constantValue, ok := o.lowerNumericConstantExprForTarget(ctx, expr.Args[0], targetType); ok {
|
|
7024
7494
|
return constantValue, diagnostics
|
|
7025
7495
|
}
|
|
7026
7496
|
}
|
|
7027
7497
|
if named := namedFunctionType(targetType); named != nil {
|
|
7498
|
+
typeName := runtimeNamedTypeName(named)
|
|
7028
7499
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperNamedFunction) +
|
|
7029
|
-
"(" + value + ", " + strconv.Quote(
|
|
7500
|
+
"(" + value + ", " + strconv.Quote(typeName) + ", " +
|
|
7501
|
+
o.runtimeFunctionTypeInfo(named.Underlying().(*types.Signature), typeName) + ")", diagnostics
|
|
7030
7502
|
}
|
|
7031
7503
|
if named := namedNonStructType(targetType); named != nil {
|
|
7032
7504
|
if _, ok := named.Underlying().(*types.Slice); ok {
|
|
@@ -7052,8 +7524,8 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
7052
7524
|
}
|
|
7053
7525
|
|
|
7054
7526
|
func (o *LoweringOwner) lowerWideIntegerBinaryExpr(ctx lowerFileContext, expr *ast.BinaryExpr, left string, right string) (string, bool) {
|
|
7055
|
-
resultWide :=
|
|
7056
|
-
leftWide :=
|
|
7527
|
+
resultWide := isRuntimeWideIntegerType(ctx.semPkg.source.TypesInfo.TypeOf(expr))
|
|
7528
|
+
leftWide := isRuntimeWideIntegerType(ctx.semPkg.source.TypesInfo.TypeOf(expr.X))
|
|
7057
7529
|
if !resultWide && !leftWide {
|
|
7058
7530
|
return "", false
|
|
7059
7531
|
}
|
|
@@ -7329,6 +7801,12 @@ func (o *LoweringOwner) lowerPointerReceiverMethodCall(
|
|
|
7329
7801
|
methodMemberName(selector.Sel.Name) + "(" + strings.Join(args, ", ") + ")"
|
|
7330
7802
|
return call, diagnostics, true
|
|
7331
7803
|
}
|
|
7804
|
+
if crossPackageUnexportedNamedType(ctx, receiver) {
|
|
7805
|
+
call := o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue) +
|
|
7806
|
+
"<any>(" + receiverExpr + ")." + methodMemberName(selector.Sel.Name) +
|
|
7807
|
+
"(" + strings.Join(args, ", ") + ")"
|
|
7808
|
+
return call, diagnostics, true
|
|
7809
|
+
}
|
|
7332
7810
|
callArgs := append([]string{receiverExpr}, args...)
|
|
7333
7811
|
call := o.namedTypeExpr(ctx, receiver) + ".prototype." + selector.Sel.Name + ".call(" + strings.Join(callArgs, ", ") + ")"
|
|
7334
7812
|
return call, diagnostics, true
|
|
@@ -8492,12 +8970,40 @@ func (o *LoweringOwner) lowerStructCompositeLit(
|
|
|
8492
8970
|
func compositeLiteralFieldNeedsPreEval(ctx lowerFileContext, expr ast.Expr) bool {
|
|
8493
8971
|
switch typed := unwrapParenExpr(expr).(type) {
|
|
8494
8972
|
case *ast.CallExpr:
|
|
8973
|
+
for _, arg := range typed.Args {
|
|
8974
|
+
if compositeLiteralFieldNeedsPreEval(ctx, arg) {
|
|
8975
|
+
return true
|
|
8976
|
+
}
|
|
8977
|
+
}
|
|
8495
8978
|
if ident, ok := typed.Fun.(*ast.Ident); ok && isBuiltinCallTarget(ctx, ident) {
|
|
8496
8979
|
return false
|
|
8497
8980
|
}
|
|
8498
8981
|
return typeFromExpr(ctx, typed.Fun) == nil
|
|
8499
8982
|
case *ast.UnaryExpr:
|
|
8500
|
-
return typed.Op == token.ARROW
|
|
8983
|
+
return typed.Op == token.ARROW || compositeLiteralFieldNeedsPreEval(ctx, typed.X)
|
|
8984
|
+
case *ast.BinaryExpr:
|
|
8985
|
+
return compositeLiteralFieldNeedsPreEval(ctx, typed.X) ||
|
|
8986
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.Y)
|
|
8987
|
+
case *ast.IndexExpr:
|
|
8988
|
+
return compositeLiteralFieldNeedsPreEval(ctx, typed.X) ||
|
|
8989
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.Index)
|
|
8990
|
+
case *ast.IndexListExpr:
|
|
8991
|
+
if compositeLiteralFieldNeedsPreEval(ctx, typed.X) {
|
|
8992
|
+
return true
|
|
8993
|
+
}
|
|
8994
|
+
for _, index := range typed.Indices {
|
|
8995
|
+
if compositeLiteralFieldNeedsPreEval(ctx, index) {
|
|
8996
|
+
return true
|
|
8997
|
+
}
|
|
8998
|
+
}
|
|
8999
|
+
return false
|
|
9000
|
+
case *ast.SliceExpr:
|
|
9001
|
+
return compositeLiteralFieldNeedsPreEval(ctx, typed.X) ||
|
|
9002
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.Low) ||
|
|
9003
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.High) ||
|
|
9004
|
+
compositeLiteralFieldNeedsPreEval(ctx, typed.Max)
|
|
9005
|
+
case *ast.StarExpr:
|
|
9006
|
+
return compositeLiteralFieldNeedsPreEval(ctx, typed.X)
|
|
8501
9007
|
default:
|
|
8502
9008
|
return false
|
|
8503
9009
|
}
|
|
@@ -8562,6 +9068,9 @@ func (o *LoweringOwner) lowerArrayCompositeLit(
|
|
|
8562
9068
|
lit *ast.CompositeLit,
|
|
8563
9069
|
array *types.Array,
|
|
8564
9070
|
) (string, []Diagnostic) {
|
|
9071
|
+
if len(lit.Elts) == 0 && isByteType(array.Elem()) {
|
|
9072
|
+
return "new Uint8Array(" + strconv.FormatInt(array.Len(), 10) + ")", nil
|
|
9073
|
+
}
|
|
8565
9074
|
values := make([]string, int(array.Len()))
|
|
8566
9075
|
for idx := range values {
|
|
8567
9076
|
values[idx] = o.lowerZeroValueExprFor(ctx, array.Elem())
|
|
@@ -8715,7 +9224,7 @@ func (o *LoweringOwner) lowerValueForTarget(
|
|
|
8715
9224
|
}
|
|
8716
9225
|
}
|
|
8717
9226
|
if isNumericType(targetType) {
|
|
8718
|
-
if constantValue, ok :=
|
|
9227
|
+
if constantValue, ok := o.lowerNumericConstantExprForTarget(ctx, expr, targetType); ok {
|
|
8719
9228
|
return constantValue
|
|
8720
9229
|
}
|
|
8721
9230
|
}
|
|
@@ -8744,6 +9253,28 @@ func lowerRealNumericConstantExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
8744
9253
|
}
|
|
8745
9254
|
}
|
|
8746
9255
|
|
|
9256
|
+
func (o *LoweringOwner) lowerNumericConstantExprForTarget(ctx lowerFileContext, expr ast.Expr, targetType types.Type) (string, bool) {
|
|
9257
|
+
if ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
9258
|
+
return "", false
|
|
9259
|
+
}
|
|
9260
|
+
tv, ok := ctx.semPkg.source.TypesInfo.Types[expr]
|
|
9261
|
+
if ok && tv.Value != nil {
|
|
9262
|
+
if bits, ok := unsignedIntegerBits(targetType); ok && bits >= 64 {
|
|
9263
|
+
if value, ok := lowerWideIntegerConstantValue(tv.Value); ok {
|
|
9264
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint) + "(" +
|
|
9265
|
+
strconv.Quote(value) + ", 64)", true
|
|
9266
|
+
}
|
|
9267
|
+
}
|
|
9268
|
+
if bits, ok := signedIntegerBits(targetType); ok && bits >= 64 {
|
|
9269
|
+
if value, ok := lowerWideIntegerConstantValue(tv.Value); ok {
|
|
9270
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperInt) + "(" +
|
|
9271
|
+
strconv.Quote(value) + ", 64)", true
|
|
9272
|
+
}
|
|
9273
|
+
}
|
|
9274
|
+
}
|
|
9275
|
+
return lowerRealNumericConstantExpr(ctx, expr)
|
|
9276
|
+
}
|
|
9277
|
+
|
|
8747
9278
|
func isRealNumericConstantExpr(ctx lowerFileContext, expr ast.Expr) bool {
|
|
8748
9279
|
if ctx.semPkg != nil && ctx.semPkg.source != nil {
|
|
8749
9280
|
if tv, ok := ctx.semPkg.source.TypesInfo.Types[expr]; ok && tv.Value != nil {
|
|
@@ -8789,6 +9320,9 @@ func (o *LoweringOwner) lowerValueForTargetTypes(
|
|
|
8789
9320
|
return wrapper
|
|
8790
9321
|
}
|
|
8791
9322
|
}
|
|
9323
|
+
if wrapper := o.lowerNumericInterfaceWrapper(ctx, targetType, sourceType, value); wrapper != "" {
|
|
9324
|
+
return wrapper
|
|
9325
|
+
}
|
|
8792
9326
|
if isInterfaceType(targetType) && isStructValueType(sourceType) {
|
|
8793
9327
|
if cloneStructValue {
|
|
8794
9328
|
value = o.lowerStructClone(value)
|
|
@@ -8837,6 +9371,25 @@ func (o *LoweringOwner) lowerValueForTargetTypes(
|
|
|
8837
9371
|
return value
|
|
8838
9372
|
}
|
|
8839
9373
|
|
|
9374
|
+
func (o *LoweringOwner) lowerNumericInterfaceWrapper(
|
|
9375
|
+
ctx lowerFileContext,
|
|
9376
|
+
targetType types.Type,
|
|
9377
|
+
sourceType types.Type,
|
|
9378
|
+
value string,
|
|
9379
|
+
) string {
|
|
9380
|
+
if targetType == nil || sourceType == nil || !isInterfaceType(targetType) || isInterfaceType(sourceType) {
|
|
9381
|
+
return ""
|
|
9382
|
+
}
|
|
9383
|
+
basic, ok := types.Unalias(sourceType).(*types.Basic)
|
|
9384
|
+
if !ok || basic.Info()&types.IsNumeric == 0 || basic.Info()&types.IsUntyped != 0 {
|
|
9385
|
+
return ""
|
|
9386
|
+
}
|
|
9387
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperNamedValueInterfaceValue) +
|
|
9388
|
+
"<" + o.tsTypeFor(ctx, targetType) + ">(" + value + ", " +
|
|
9389
|
+
strconv.Quote(goRuntimeTypeString(sourceType)) + ", {}, " +
|
|
9390
|
+
o.runtimeTypeInfoExpr(sourceType) + ")"
|
|
9391
|
+
}
|
|
9392
|
+
|
|
8840
9393
|
func isBasicFixedWideIntegerType(typ types.Type) bool {
|
|
8841
9394
|
basic, ok := types.Unalias(typ).(*types.Basic)
|
|
8842
9395
|
if !ok {
|
|
@@ -8876,7 +9429,8 @@ func (o *LoweringOwner) lowerNamedValueInterfaceWrapper(
|
|
|
8876
9429
|
}
|
|
8877
9430
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperNamedValueInterfaceValue) +
|
|
8878
9431
|
"<" + o.tsTypeFor(ctx, targetType) + ">(" + value + ", " +
|
|
8879
|
-
strconv.Quote(goRuntimeTypeString(sourceType)) + ", " + methods + "
|
|
9432
|
+
strconv.Quote(goRuntimeTypeString(sourceType)) + ", " + methods + ", " +
|
|
9433
|
+
o.runtimeTypeInfoExpr(sourceType) + ")"
|
|
8880
9434
|
}
|
|
8881
9435
|
|
|
8882
9436
|
func (o *LoweringOwner) lowerPrimitiveErrorWrapper(ctx lowerFileContext, sourceType types.Type, value string) string {
|
|
@@ -8898,7 +9452,8 @@ func (o *LoweringOwner) lowerPrimitiveErrorWrapper(ctx lowerFileContext, sourceT
|
|
|
8898
9452
|
}
|
|
8899
9453
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperNamedValueInterfaceValue) +
|
|
8900
9454
|
"<$.GoError>(" + value + ", " + strconv.Quote(goRuntimeTypeString(sourceType)) +
|
|
8901
|
-
", {\"Error\": " + o.methodFunctionExpr(ctx, named, fn, "Error") + "}
|
|
9455
|
+
", {\"Error\": " + o.methodFunctionExpr(ctx, named, fn, "Error") + "}, " +
|
|
9456
|
+
o.runtimeTypeInfoExpr(sourceType) + ")"
|
|
8902
9457
|
}
|
|
8903
9458
|
|
|
8904
9459
|
func (o *LoweringOwner) lowerStructClone(value string) string {
|
|
@@ -8955,7 +9510,7 @@ func (o *LoweringOwner) lowerZeroValueExprFor(ctx lowerFileContext, typ types.Ty
|
|
|
8955
9510
|
|
|
8956
9511
|
func (o *LoweringOwner) lowerDeclarationZeroValueExpr(ctx lowerFileContext, typ types.Type) string {
|
|
8957
9512
|
if isFunctionType(typ) {
|
|
8958
|
-
return "null as " + o.
|
|
9513
|
+
return "null as unknown as " + o.tsFunctionZeroValueTypeFor(ctx, typ)
|
|
8959
9514
|
}
|
|
8960
9515
|
typeParam, ok := types.Unalias(typ).(*types.TypeParam)
|
|
8961
9516
|
if !ok {
|
|
@@ -8972,6 +9527,13 @@ func (o *LoweringOwner) lowerDeclarationZeroValueExpr(ctx lowerFileContext, typ
|
|
|
8972
9527
|
"(__typeArgs, " + strconv.Quote(typeParam.Obj().Name()) + ", " + zeroValueExpr(typ) + ")"
|
|
8973
9528
|
}
|
|
8974
9529
|
|
|
9530
|
+
func (o *LoweringOwner) tsFunctionZeroValueTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
9531
|
+
if signature := unnamedSignatureForType(typ); signature != nil {
|
|
9532
|
+
return o.tsAsyncCompatibleFunctionTypeFor(ctx, signature)
|
|
9533
|
+
}
|
|
9534
|
+
return o.tsTypeFor(ctx, typ)
|
|
9535
|
+
}
|
|
9536
|
+
|
|
8975
9537
|
func (o *LoweringOwner) runtimeTypeInfoExpr(typ types.Type) string {
|
|
8976
9538
|
return o.runtimeTypeInfoExprWithSeen(typ, make(map[types.Type]bool))
|
|
8977
9539
|
}
|
|
@@ -9062,7 +9624,7 @@ func (o *LoweringOwner) shallowRuntimeTypeInfoExpr(typ types.Type) string {
|
|
|
9062
9624
|
case *types.Pointer:
|
|
9063
9625
|
return "{ kind: " + typeKind + ".Pointer, elemType: { kind: " + typeKind + ".Basic, name: \"unknown\" } }"
|
|
9064
9626
|
case *types.Struct:
|
|
9065
|
-
return "{ kind: " + typeKind + ".Struct, methods: [], fields:
|
|
9627
|
+
return "{ kind: " + typeKind + ".Struct, methods: [], fields: [] }"
|
|
9066
9628
|
case *types.Slice:
|
|
9067
9629
|
return "{ kind: " + typeKind + ".Slice, elemType: { kind: " + typeKind + ".Basic, name: \"unknown\" } }"
|
|
9068
9630
|
case *types.Array:
|
|
@@ -9078,6 +9640,11 @@ func (o *LoweringOwner) shallowRuntimeTypeInfoExpr(typ types.Type) string {
|
|
|
9078
9640
|
|
|
9079
9641
|
func (o *LoweringOwner) runtimeStructFieldsExpr(structType *types.Struct, seen map[types.Type]bool) string {
|
|
9080
9642
|
fields := make([]string, 0, structType.NumFields())
|
|
9643
|
+
var vars []*types.Var
|
|
9644
|
+
for field := range structType.Fields() {
|
|
9645
|
+
vars = append(vars, field)
|
|
9646
|
+
}
|
|
9647
|
+
offsets := structFieldOffsets(goScriptTypeSizes(), vars)
|
|
9081
9648
|
for idx := range structType.NumFields() {
|
|
9082
9649
|
field := structType.Field(idx)
|
|
9083
9650
|
fieldName := tsStructFieldName(field.Name(), idx)
|
|
@@ -9085,30 +9652,71 @@ func (o *LoweringOwner) runtimeStructFieldsExpr(structType *types.Struct, seen m
|
|
|
9085
9652
|
if fieldName != field.Name() {
|
|
9086
9653
|
runtimeName = field.Name()
|
|
9087
9654
|
}
|
|
9655
|
+
pkgPath := ""
|
|
9656
|
+
if !field.Exported() && field.Pkg() != nil {
|
|
9657
|
+
pkgPath = field.Pkg().Path()
|
|
9658
|
+
}
|
|
9088
9659
|
fieldInfo := runtimeStructFieldInfoExpr(
|
|
9089
9660
|
o.runtimeTypeInfoExprWithSeen(field.Type(), seen),
|
|
9661
|
+
fieldName,
|
|
9090
9662
|
runtimeName,
|
|
9091
9663
|
structType.Tag(idx),
|
|
9664
|
+
pkgPath,
|
|
9665
|
+
field.Embedded(),
|
|
9666
|
+
[]int{idx},
|
|
9667
|
+
offsets[idx],
|
|
9668
|
+
field.Exported(),
|
|
9092
9669
|
)
|
|
9093
|
-
fields = append(fields,
|
|
9670
|
+
fields = append(fields, fieldInfo)
|
|
9094
9671
|
}
|
|
9095
|
-
return "
|
|
9672
|
+
return "[" + strings.Join(fields, ", ") + "]"
|
|
9096
9673
|
}
|
|
9097
9674
|
|
|
9098
|
-
func runtimeStructFieldInfoExpr(
|
|
9099
|
-
|
|
9100
|
-
|
|
9675
|
+
func runtimeStructFieldInfoExpr(
|
|
9676
|
+
runtimeType string,
|
|
9677
|
+
storageKey string,
|
|
9678
|
+
runtimeName string,
|
|
9679
|
+
tag string,
|
|
9680
|
+
pkgPath string,
|
|
9681
|
+
anonymous bool,
|
|
9682
|
+
index []int,
|
|
9683
|
+
offset int64,
|
|
9684
|
+
exported bool,
|
|
9685
|
+
) string {
|
|
9686
|
+
name := runtimeName
|
|
9687
|
+
if name == "" {
|
|
9688
|
+
name = storageKey
|
|
9689
|
+
}
|
|
9690
|
+
fields := []string{
|
|
9691
|
+
"name: " + strconv.Quote(name),
|
|
9692
|
+
"key: " + strconv.Quote(storageKey),
|
|
9693
|
+
"type: " + runtimeType,
|
|
9101
9694
|
}
|
|
9102
|
-
fields := []string{"type: " + runtimeType}
|
|
9103
9695
|
if runtimeName != "" {
|
|
9104
|
-
fields = append(fields, "
|
|
9696
|
+
fields = append(fields, "pkgPath: "+strconv.Quote(pkgPath))
|
|
9697
|
+
} else if pkgPath != "" {
|
|
9698
|
+
fields = append(fields, "pkgPath: "+strconv.Quote(pkgPath))
|
|
9105
9699
|
}
|
|
9106
9700
|
if tag != "" {
|
|
9107
9701
|
fields = append(fields, "tag: "+strconv.Quote(tag))
|
|
9108
9702
|
}
|
|
9703
|
+
if anonymous {
|
|
9704
|
+
fields = append(fields, "anonymous: true")
|
|
9705
|
+
}
|
|
9706
|
+
fields = append(fields, "index: "+runtimeStructFieldIndexExpr(index))
|
|
9707
|
+
fields = append(fields, "offset: "+strconv.FormatInt(offset, 10))
|
|
9708
|
+
fields = append(fields, "exported: "+strconv.FormatBool(exported))
|
|
9109
9709
|
return "{ " + strings.Join(fields, ", ") + " }"
|
|
9110
9710
|
}
|
|
9111
9711
|
|
|
9712
|
+
func runtimeStructFieldIndexExpr(index []int) string {
|
|
9713
|
+
values := make([]string, 0, len(index))
|
|
9714
|
+
for _, value := range index {
|
|
9715
|
+
values = append(values, strconv.Itoa(value))
|
|
9716
|
+
}
|
|
9717
|
+
return "[" + strings.Join(values, ", ") + "]"
|
|
9718
|
+
}
|
|
9719
|
+
|
|
9112
9720
|
func (o *LoweringOwner) runtimeFunctionTypeInfo(signature *types.Signature, name string) string {
|
|
9113
9721
|
return o.runtimeFunctionTypeInfoWithSeen(signature, name, make(map[types.Type]bool))
|
|
9114
9722
|
}
|
|
@@ -9588,6 +10196,11 @@ func namedFunctionType(typ types.Type) *types.Named {
|
|
|
9588
10196
|
return named
|
|
9589
10197
|
}
|
|
9590
10198
|
|
|
10199
|
+
func overrideNamedStringType(ctx lowerFileContext, owner *LoweringOwner, typ types.Type) bool {
|
|
10200
|
+
named, _ := types.Unalias(typ).(*types.Named)
|
|
10201
|
+
return named != nil && isStringType(named) && owner.typeUsesOverride(named)
|
|
10202
|
+
}
|
|
10203
|
+
|
|
9591
10204
|
func isBuiltinErrorType(typ types.Type) bool {
|
|
9592
10205
|
if typ == nil {
|
|
9593
10206
|
return false
|
|
@@ -9738,6 +10351,16 @@ func isStructValueType(typ types.Type) bool {
|
|
|
9738
10351
|
return namedStructType(typ) != nil
|
|
9739
10352
|
}
|
|
9740
10353
|
|
|
10354
|
+
func isStructComparableType(typ types.Type) bool {
|
|
10355
|
+
if typ == nil {
|
|
10356
|
+
return false
|
|
10357
|
+
}
|
|
10358
|
+
if _, ok := types.Unalias(typ).Underlying().(*types.Struct); !ok {
|
|
10359
|
+
return false
|
|
10360
|
+
}
|
|
10361
|
+
return types.Comparable(typ)
|
|
10362
|
+
}
|
|
10363
|
+
|
|
9741
10364
|
func isPointerToStructType(typ types.Type) bool {
|
|
9742
10365
|
pointer, ok := types.Unalias(typ).Underlying().(*types.Pointer)
|
|
9743
10366
|
if !ok {
|
|
@@ -9917,6 +10540,14 @@ func isFixedSignedWideIntegerType(typ types.Type) bool {
|
|
|
9917
10540
|
return ok && basic.Kind() == types.Int64
|
|
9918
10541
|
}
|
|
9919
10542
|
|
|
10543
|
+
func isRuntimeWideIntegerType(typ types.Type) bool {
|
|
10544
|
+
if isFixedWideIntegerType(typ) {
|
|
10545
|
+
return true
|
|
10546
|
+
}
|
|
10547
|
+
bits, ok := unsignedIntegerBits(typ)
|
|
10548
|
+
return ok && bits > 32
|
|
10549
|
+
}
|
|
10550
|
+
|
|
9920
10551
|
func isRuneSliceType(typ types.Type) bool {
|
|
9921
10552
|
slice, ok := types.Unalias(typ).Underlying().(*types.Slice)
|
|
9922
10553
|
return ok && isRuneType(slice.Elem())
|
|
@@ -10002,8 +10633,7 @@ func (o *LoweringOwner) functionAsync(ctx lowerFileContext, fn *types.Func) bool
|
|
|
10002
10633
|
if fn == nil || ctx.model == nil {
|
|
10003
10634
|
return false
|
|
10004
10635
|
}
|
|
10005
|
-
|
|
10006
|
-
return semFn != nil && semFn.async
|
|
10636
|
+
return ctx.model.functionAsync(fn)
|
|
10007
10637
|
}
|
|
10008
10638
|
|
|
10009
10639
|
func (o *LoweringOwner) callNeedsAwait(ctx lowerFileContext, fun ast.Expr) bool {
|
|
@@ -10152,6 +10782,18 @@ func (o *LoweringOwner) inferGenericTypeArg(
|
|
|
10152
10782
|
}
|
|
10153
10783
|
return
|
|
10154
10784
|
}
|
|
10785
|
+
if paramNamed, ok := types.Unalias(paramType).(*types.Named); ok {
|
|
10786
|
+
if argNamed, ok := types.Unalias(argType).(*types.Named); ok &&
|
|
10787
|
+
namedOriginsEqual(paramNamed, argNamed) {
|
|
10788
|
+
paramArgs := paramNamed.TypeArgs()
|
|
10789
|
+
argArgs := argNamed.TypeArgs()
|
|
10790
|
+
if paramArgs != nil && argArgs != nil {
|
|
10791
|
+
for idx := range min(paramArgs.Len(), argArgs.Len()) {
|
|
10792
|
+
o.inferGenericTypeArg(inferred, paramArgs.At(idx), argArgs.At(idx))
|
|
10793
|
+
}
|
|
10794
|
+
}
|
|
10795
|
+
}
|
|
10796
|
+
}
|
|
10155
10797
|
switch param := types.Unalias(paramType).Underlying().(type) {
|
|
10156
10798
|
case *types.Slice:
|
|
10157
10799
|
if arg, ok := types.Unalias(argType).Underlying().(*types.Slice); ok {
|
|
@@ -10164,6 +10806,24 @@ func (o *LoweringOwner) inferGenericTypeArg(
|
|
|
10164
10806
|
}
|
|
10165
10807
|
}
|
|
10166
10808
|
|
|
10809
|
+
func namedOriginsEqual(a, b *types.Named) bool {
|
|
10810
|
+
if a == nil || b == nil {
|
|
10811
|
+
return false
|
|
10812
|
+
}
|
|
10813
|
+
aOrigin := a.Origin()
|
|
10814
|
+
if aOrigin == nil {
|
|
10815
|
+
aOrigin = a
|
|
10816
|
+
}
|
|
10817
|
+
bOrigin := b.Origin()
|
|
10818
|
+
if bOrigin == nil {
|
|
10819
|
+
bOrigin = b
|
|
10820
|
+
}
|
|
10821
|
+
if aOrigin.Obj() == nil || bOrigin.Obj() == nil {
|
|
10822
|
+
return aOrigin == bOrigin
|
|
10823
|
+
}
|
|
10824
|
+
return aOrigin.Obj() == bOrigin.Obj()
|
|
10825
|
+
}
|
|
10826
|
+
|
|
10167
10827
|
func (o *LoweringOwner) genericTypeDescriptorExpr(ctx lowerFileContext, typ types.Type) string {
|
|
10168
10828
|
if typeParam, ok := types.Unalias(typ).(*types.TypeParam); ok && typeParamInScope(ctx, typeParam) {
|
|
10169
10829
|
return "__typeArgs?.[" + strconv.Quote(typeParam.Obj().Name()) + "] ?? { type: " +
|
|
@@ -10175,16 +10835,28 @@ func (o *LoweringOwner) genericTypeDescriptorExpr(ctx lowerFileContext, typ type
|
|
|
10175
10835
|
}
|
|
10176
10836
|
if methods := o.genericMethodDescriptors(ctx, typ); methods != "" {
|
|
10177
10837
|
parts = append(parts, "methods: "+methods)
|
|
10838
|
+
if signatures := o.genericMethodSignatureDescriptors(typ); signatures != "" &&
|
|
10839
|
+
genericTypeDescriptorNeedsMethodSignatures(typ) {
|
|
10840
|
+
parts = append(parts, "methodSignatures: "+signatures)
|
|
10841
|
+
}
|
|
10178
10842
|
}
|
|
10179
10843
|
return "{ " + strings.Join(parts, ", ") + " }"
|
|
10180
10844
|
}
|
|
10181
10845
|
|
|
10846
|
+
func genericTypeDescriptorNeedsMethodSignatures(typ types.Type) bool {
|
|
10847
|
+
named, _ := genericMethodSetDescriptorTarget(typ)
|
|
10848
|
+
if named == nil {
|
|
10849
|
+
return false
|
|
10850
|
+
}
|
|
10851
|
+
return namedStructType(named) == nil && !isInterfaceType(named)
|
|
10852
|
+
}
|
|
10853
|
+
|
|
10182
10854
|
func (o *LoweringOwner) genericMethodDescriptors(ctx lowerFileContext, typ types.Type) string {
|
|
10183
|
-
named,
|
|
10855
|
+
named, methodSetType := genericMethodSetDescriptorTarget(typ)
|
|
10184
10856
|
if named == nil {
|
|
10185
10857
|
return ""
|
|
10186
10858
|
}
|
|
10187
|
-
return o.genericMethodDescriptorsForType(ctx, named,
|
|
10859
|
+
return o.genericMethodDescriptorsForType(ctx, named, methodSetType)
|
|
10188
10860
|
}
|
|
10189
10861
|
|
|
10190
10862
|
func (o *LoweringOwner) genericMethodDescriptorsForType(
|
|
@@ -10225,6 +10897,33 @@ func (o *LoweringOwner) genericMethodDescriptorsForType(
|
|
|
10225
10897
|
return "{" + strings.Join(methods, ", ") + "}"
|
|
10226
10898
|
}
|
|
10227
10899
|
|
|
10900
|
+
func (o *LoweringOwner) genericMethodSignatureDescriptors(typ types.Type) string {
|
|
10901
|
+
_, methodSetType := genericMethodSetDescriptorTarget(typ)
|
|
10902
|
+
if methodSetType == nil {
|
|
10903
|
+
return ""
|
|
10904
|
+
}
|
|
10905
|
+
methodSet := types.NewMethodSet(methodSetType)
|
|
10906
|
+
methods := make([]string, 0, methodSet.Len())
|
|
10907
|
+
for method := range methodSet.Methods() {
|
|
10908
|
+
fn, _ := method.Obj().(*types.Func)
|
|
10909
|
+
if fn != nil {
|
|
10910
|
+
methods = append(methods, o.runtimeMethodSignature(fn, make(map[types.Type]bool)))
|
|
10911
|
+
}
|
|
10912
|
+
}
|
|
10913
|
+
if len(methods) == 0 {
|
|
10914
|
+
return ""
|
|
10915
|
+
}
|
|
10916
|
+
return "[" + strings.Join(methods, ", ") + "]"
|
|
10917
|
+
}
|
|
10918
|
+
|
|
10919
|
+
func genericMethodSetDescriptorTarget(typ types.Type) (*types.Named, types.Type) {
|
|
10920
|
+
named, _ := types.Unalias(typ).(*types.Named)
|
|
10921
|
+
if named == nil {
|
|
10922
|
+
return namedNonStructMethodSetType(typ)
|
|
10923
|
+
}
|
|
10924
|
+
return named, named
|
|
10925
|
+
}
|
|
10926
|
+
|
|
10228
10927
|
func namedNonStructMethodSetType(typ types.Type) (*types.Named, types.Type) {
|
|
10229
10928
|
if named := namedNonStructType(typ); named != nil {
|
|
10230
10929
|
return named, named
|
|
@@ -10377,6 +11076,32 @@ func basicRuntimeName(basic *types.Basic) string {
|
|
|
10377
11076
|
return "bool"
|
|
10378
11077
|
case types.String:
|
|
10379
11078
|
return "string"
|
|
11079
|
+
case types.Int:
|
|
11080
|
+
return "int"
|
|
11081
|
+
case types.Int8:
|
|
11082
|
+
return "int8"
|
|
11083
|
+
case types.Int16:
|
|
11084
|
+
return "int16"
|
|
11085
|
+
case types.Int32:
|
|
11086
|
+
return "int32"
|
|
11087
|
+
case types.Int64:
|
|
11088
|
+
return "int64"
|
|
11089
|
+
case types.Uint:
|
|
11090
|
+
return "uint"
|
|
11091
|
+
case types.Uint8:
|
|
11092
|
+
return "uint8"
|
|
11093
|
+
case types.Uint16:
|
|
11094
|
+
return "uint16"
|
|
11095
|
+
case types.Uint32:
|
|
11096
|
+
return "uint32"
|
|
11097
|
+
case types.Uint64:
|
|
11098
|
+
return "uint64"
|
|
11099
|
+
case types.Uintptr:
|
|
11100
|
+
return "uintptr"
|
|
11101
|
+
case types.Float32:
|
|
11102
|
+
return "float32"
|
|
11103
|
+
case types.Float64:
|
|
11104
|
+
return "float64"
|
|
10380
11105
|
case types.Complex64:
|
|
10381
11106
|
return "complex64"
|
|
10382
11107
|
case types.Complex128:
|