goscript 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cmd/goscript/cmd-test.go +104 -11
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript/cmd_compile.go +9 -0
- package/compiler/compile-request.go +31 -0
- package/compiler/compiler.go +1 -1
- package/compiler/compliance_test.go +0 -2
- package/compiler/config.go +2 -0
- package/compiler/gotest/package-result.go +2 -0
- package/compiler/gotest/request.go +85 -20
- package/compiler/gotest/runner.go +733 -96
- package/compiler/gotest/runner_test.go +647 -3
- package/compiler/lowered-program.go +9 -2
- package/compiler/lowering.go +2001 -345
- package/compiler/override-facts.go +77 -27
- package/compiler/override-registry.go +5 -4
- package/compiler/override-registry_test.go +135 -0
- package/compiler/package-graph_test.go +62 -7
- package/compiler/package-test-graph-variant.go +40 -16
- package/compiler/package-test-graph.go +0 -5
- package/compiler/package-test-graph_test.go +61 -3
- package/compiler/runtime-contract.go +40 -0
- package/compiler/semantic-model-types.go +16 -0
- package/compiler/semantic-model.go +336 -91
- package/compiler/semantic-model_test.go +50 -1
- package/compiler/service.go +9 -3
- package/compiler/skeleton_test.go +1921 -298
- package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
- package/compiler/tsworkspace/owner.go +8 -0
- package/compiler/tsworkspace/tool-process-other.go +14 -0
- package/compiler/tsworkspace/tool-process-unix.go +19 -0
- package/compiler/typescript-emitter.go +122 -9
- package/dist/gs/builtin/builtin.d.ts +20 -1
- package/dist/gs/builtin/builtin.js +246 -26
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +24 -10
- package/dist/gs/builtin/channel.js +107 -25
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/defer.d.ts +1 -0
- package/dist/gs/builtin/defer.js +12 -2
- package/dist/gs/builtin/defer.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +9 -0
- package/dist/gs/builtin/hostio.js +25 -0
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/map.js +40 -6
- package/dist/gs/builtin/map.js.map +1 -1
- package/dist/gs/builtin/print.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +43 -9
- package/dist/gs/builtin/slice.js +437 -234
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +2 -0
- package/dist/gs/builtin/type.js +47 -7
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +2 -0
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +28 -28
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/iter.gs.js +13 -13
- package/dist/gs/bytes/iter.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +26 -0
- package/dist/gs/compress/zlib/index.js +168 -0
- package/dist/gs/compress/zlib/index.js.map +1 -0
- package/dist/gs/context/context.d.ts +1 -1
- package/dist/gs/context/context.js +8 -3
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/ecdh/index.d.ts +52 -0
- package/dist/gs/crypto/ecdh/index.js +226 -0
- package/dist/gs/crypto/ecdh/index.js.map +1 -0
- package/dist/gs/crypto/ed25519/index.d.ts +34 -0
- package/dist/gs/crypto/ed25519/index.js +160 -0
- package/dist/gs/crypto/ed25519/index.js.map +1 -0
- package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
- package/dist/gs/crypto/internal/constanttime/index.js +18 -0
- package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
- package/dist/gs/crypto/rand/index.d.ts +2 -0
- package/dist/gs/crypto/rand/index.js +85 -0
- package/dist/gs/crypto/rand/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.d.ts +8 -0
- package/dist/gs/crypto/sha256/index.js +118 -0
- package/dist/gs/crypto/sha256/index.js.map +1 -0
- package/dist/gs/crypto/sha512/index.d.ts +14 -0
- package/dist/gs/crypto/sha512/index.js +129 -0
- package/dist/gs/crypto/sha512/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +3 -0
- package/dist/gs/encoding/json/index.js +15 -0
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.js +29 -6
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +7 -7
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +52 -18
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +56 -20
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +57 -3
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +366 -1
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js +3 -2
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -1
- package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
- package/dist/gs/go/token/index.js +11 -4
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/fnv/index.d.ts +57 -0
- package/dist/gs/hash/fnv/index.js +299 -0
- package/dist/gs/hash/fnv/index.js.map +1 -0
- package/dist/gs/hash/index.d.ts +17 -0
- package/dist/gs/hash/index.js +94 -0
- package/dist/gs/hash/index.js.map +1 -0
- package/dist/gs/io/fs/readlink.js +2 -6
- package/dist/gs/io/fs/readlink.js.map +1 -1
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/iter/iter.d.ts +3 -2
- package/dist/gs/iter/iter.js.map +1 -1
- package/dist/gs/maps/iter.d.ts +5 -5
- package/dist/gs/maps/iter.js +48 -21
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.d.ts +6 -6
- package/dist/gs/math/bits/index.js +14 -24
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.js +3 -1
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +20 -1
- package/dist/gs/net/http/httptest/index.js +83 -3
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +110 -6
- package/dist/gs/net/http/index.js +262 -16
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/net/http/pprof/index.d.ts +8 -0
- package/dist/gs/net/http/pprof/index.js +59 -0
- package/dist/gs/net/http/pprof/index.js.map +1 -0
- package/dist/gs/os/error.gs.js +9 -7
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +95 -15
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.d.ts +5 -3
- package/dist/gs/path/filepath/path.js +65 -10
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +3 -2
- package/dist/gs/reflect/index.js +2 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/iter.js +2 -2
- package/dist/gs/reflect/iter.js.map +1 -1
- package/dist/gs/reflect/map.js +26 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +24 -5
- package/dist/gs/reflect/type.js +390 -38
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +1 -0
- package/dist/gs/reflect/types.js +3 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +4 -1
- package/dist/gs/reflect/value.js +39 -1
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +1 -1
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/debug/index.d.ts +39 -0
- package/dist/gs/runtime/debug/index.js +58 -0
- package/dist/gs/runtime/debug/index.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +20 -0
- package/dist/gs/runtime/pprof/index.js +85 -0
- package/dist/gs/runtime/pprof/index.js.map +1 -0
- package/dist/gs/runtime/trace/index.d.ts +19 -0
- package/dist/gs/runtime/trace/index.js +64 -0
- package/dist/gs/runtime/trace/index.js.map +1 -0
- package/dist/gs/slices/slices.d.ts +24 -9
- package/dist/gs/slices/slices.js +229 -24
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/slice.gs.d.ts +5 -3
- package/dist/gs/sort/slice.gs.js +55 -17
- package/dist/gs/sort/slice.gs.js.map +1 -1
- package/dist/gs/strings/builder.js +26 -17
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/strings/iter.js +140 -75
- package/dist/gs/strings/iter.js.map +1 -1
- package/dist/gs/strings/replace.js +2 -2
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.js +52 -6
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +6 -3
- package/dist/gs/sync/sync.js +39 -11
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/errors.d.ts +116 -112
- package/dist/gs/syscall/errors.js +38 -1
- package/dist/gs/syscall/errors.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +2 -8
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/syscall/js/index.js +20 -12
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/syscall/types.d.ts +4 -1
- package/dist/gs/syscall/types.js.map +1 -1
- package/dist/gs/testing/testing.d.ts +4 -3
- package/dist/gs/testing/testing.js +21 -4
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.js +22 -0
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/dist/gs/unique/index.js +7 -2
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +8 -8
- package/go.sum +14 -23
- package/gs/builtin/builtin.ts +364 -37
- package/gs/builtin/channel.ts +161 -29
- package/gs/builtin/defer.ts +13 -2
- package/gs/builtin/hostio.test.ts +1 -0
- package/gs/builtin/hostio.ts +38 -0
- package/gs/builtin/map.ts +46 -6
- package/gs/builtin/print.ts +12 -3
- package/gs/builtin/runtime-contract.test.ts +257 -10
- package/gs/builtin/slice.test.ts +70 -0
- package/gs/builtin/slice.ts +566 -255
- package/gs/builtin/type.ts +53 -9
- package/gs/builtin/varRef.ts +2 -0
- package/gs/bytes/buffer.gs.ts +28 -28
- package/gs/bytes/iter.gs.ts +13 -14
- package/gs/compress/zlib/index.test.ts +28 -0
- package/gs/compress/zlib/index.ts +200 -0
- package/gs/compress/zlib/meta.json +3 -0
- package/gs/context/context.test.ts +31 -1
- package/gs/context/context.ts +9 -4
- package/gs/crypto/ecdh/index.test.ts +43 -0
- package/gs/crypto/ecdh/index.ts +274 -0
- package/gs/crypto/ed25519/index.test.ts +41 -0
- package/gs/crypto/ed25519/index.ts +238 -0
- package/gs/crypto/ed25519/meta.json +13 -0
- package/gs/crypto/internal/constanttime/index.test.ts +25 -0
- package/gs/crypto/internal/constanttime/index.ts +22 -0
- package/gs/crypto/rand/index.test.ts +89 -1
- package/gs/crypto/rand/index.ts +103 -1
- package/gs/crypto/rand/meta.json +4 -1
- package/gs/crypto/sha256/index.test.ts +78 -0
- package/gs/crypto/sha256/index.ts +150 -0
- package/gs/crypto/sha256/meta.json +9 -0
- package/gs/crypto/sha512/index.test.ts +31 -0
- package/gs/crypto/sha512/index.ts +161 -0
- package/gs/crypto/sha512/meta.json +11 -0
- package/gs/encoding/json/index.test.ts +25 -3
- package/gs/encoding/json/index.ts +21 -3
- package/gs/errors/errors.test.ts +4 -1
- package/gs/errors/errors.ts +32 -8
- package/gs/fmt/fmt.test.ts +3 -1
- package/gs/fmt/fmt.ts +1 -5
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +62 -7
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +78 -36
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +32 -11
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +122 -43
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +518 -4
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +6 -0
- package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
- package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
- package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
- package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
- package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
- package/gs/github.com/klauspost/compress/internal/le/index.test.ts +2 -1
- package/gs/github.com/klauspost/compress/internal/le/index.ts +6 -5
- package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
- package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
- package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
- package/gs/go/token/index.ts +17 -4
- package/gs/hash/fnv/index.test.ts +67 -0
- package/gs/hash/fnv/index.ts +351 -0
- package/gs/hash/fnv/meta.json +3 -0
- package/gs/hash/index.test.ts +37 -0
- package/gs/hash/index.ts +118 -0
- package/gs/hash/meta.json +5 -0
- package/gs/internal/byteorder/index.test.ts +6 -6
- package/gs/io/fs/readlink.ts +40 -48
- package/gs/io/fs/walk.ts +10 -2
- package/gs/io/io.ts +4 -1
- package/gs/iter/iter.ts +8 -2
- package/gs/maps/iter.ts +69 -26
- package/gs/maps/maps.test.ts +23 -0
- package/gs/maps/maps.ts +6 -6
- package/gs/math/bits/index.test.ts +20 -0
- package/gs/math/bits/index.ts +15 -28
- package/gs/mime/index.ts +8 -2
- package/gs/net/http/httptest/index.test.ts +53 -0
- package/gs/net/http/httptest/index.ts +98 -3
- package/gs/net/http/index.test.ts +129 -1
- package/gs/net/http/index.ts +370 -19
- package/gs/net/http/meta.json +6 -0
- package/gs/net/http/pprof/index.test.ts +47 -0
- package/gs/net/http/pprof/index.ts +65 -0
- package/gs/os/error.gs.ts +9 -10
- package/gs/os/error.test.ts +41 -0
- package/gs/os/file_unix_js.test.ts +55 -0
- package/gs/os/tempfile.gs.test.ts +37 -10
- package/gs/os/types_js.gs.ts +94 -15
- package/gs/path/filepath/match.ts +4 -1
- package/gs/path/filepath/meta.json +6 -0
- package/gs/path/filepath/path.test.ts +57 -2
- package/gs/path/filepath/path.ts +91 -12
- package/gs/reflect/field.test.ts +63 -0
- package/gs/reflect/index.ts +4 -1
- package/gs/reflect/iter.ts +2 -2
- package/gs/reflect/map.test.ts +24 -2
- package/gs/reflect/map.ts +35 -0
- package/gs/reflect/type.ts +543 -60
- package/gs/reflect/typefor.test.ts +100 -0
- package/gs/reflect/types.ts +3 -1
- package/gs/reflect/value.ts +50 -1
- package/gs/reflect/visiblefields.ts +1 -1
- package/gs/runtime/debug/index.test.ts +22 -1
- package/gs/runtime/debug/index.ts +88 -0
- package/gs/runtime/pprof/index.test.ts +36 -0
- package/gs/runtime/pprof/index.ts +104 -0
- package/gs/runtime/pprof/meta.json +6 -0
- package/gs/runtime/trace/index.test.ts +45 -0
- package/gs/runtime/trace/index.ts +97 -0
- package/gs/runtime/trace/meta.json +7 -0
- package/gs/slices/meta.json +2 -1
- package/gs/slices/slices.test.ts +86 -0
- package/gs/slices/slices.ts +284 -37
- package/gs/sort/slice.gs.ts +73 -23
- package/gs/sort/slice.test.ts +40 -0
- package/gs/strings/builder.test.ts +8 -0
- package/gs/strings/builder.ts +29 -17
- package/gs/strings/iter.test.ts +5 -7
- package/gs/strings/iter.ts +146 -71
- package/gs/strings/replace.test.ts +1 -4
- package/gs/strings/replace.ts +6 -6
- package/gs/strings/strings.test.ts +4 -0
- package/gs/strings/strings.ts +54 -6
- package/gs/sync/sync.test.ts +57 -1
- package/gs/sync/sync.ts +45 -13
- package/gs/syscall/errors.ts +158 -115
- package/gs/syscall/fs.ts +8 -8
- package/gs/syscall/js/index.ts +49 -22
- package/gs/syscall/net.test.ts +26 -0
- package/gs/syscall/types.ts +7 -2
- package/gs/testing/testing.test.ts +56 -0
- package/gs/testing/testing.ts +27 -10
- package/gs/time/meta.json +2 -2
- package/gs/time/time.test.ts +4 -0
- package/gs/time/time.ts +33 -2
- package/gs/unicode/unicode.test.ts +14 -3
- package/gs/unicode/unicode.ts +1 -5
- package/gs/unique/index.ts +9 -2
- package/package.json +3 -3
package/compiler/lowering.go
CHANGED
|
@@ -15,6 +15,7 @@ import (
|
|
|
15
15
|
"slices"
|
|
16
16
|
"strconv"
|
|
17
17
|
"strings"
|
|
18
|
+
"unicode/utf8"
|
|
18
19
|
)
|
|
19
20
|
|
|
20
21
|
// LoweringOwner owns conversion from the semantic model to compiler IR.
|
|
@@ -86,10 +87,13 @@ func (o *LoweringOwner) lowerPackage(model *SemanticModel, semPkg *semanticPacka
|
|
|
86
87
|
pkgPath: semPkg.pkgPath,
|
|
87
88
|
name: semPkg.name,
|
|
88
89
|
}
|
|
90
|
+
declFiles := packageDeclFiles(semPkg)
|
|
91
|
+
outputNames := packageOutputNames(semPkg)
|
|
92
|
+
lazyPackageVars := o.lazyPackageVars(semPkg, declFiles)
|
|
89
93
|
var diagnostics []Diagnostic
|
|
90
94
|
for idx, file := range semPkg.source.Syntax {
|
|
91
95
|
sourcePath := sourceFilePath(semPkg, idx, file)
|
|
92
|
-
loweredFile, fileDiagnostics := o.lowerFile(model, semPkg, file, sourcePath)
|
|
96
|
+
loweredFile, fileDiagnostics := o.lowerFile(model, semPkg, file, sourcePath, declFiles, outputNames, lazyPackageVars)
|
|
93
97
|
diagnostics = append(diagnostics, fileDiagnostics...)
|
|
94
98
|
if loweredFile != nil {
|
|
95
99
|
loweredPkg.files = append(loweredPkg.files, loweredFile)
|
|
@@ -118,6 +122,9 @@ func (o *LoweringOwner) lowerFile(
|
|
|
118
122
|
semPkg *semanticPackage,
|
|
119
123
|
file *ast.File,
|
|
120
124
|
sourcePath string,
|
|
125
|
+
declFiles map[types.Object]string,
|
|
126
|
+
outputNames map[string]string,
|
|
127
|
+
lazyPackageVars map[types.Object]bool,
|
|
121
128
|
) (*loweredFile, []Diagnostic) {
|
|
122
129
|
associatedMethods := o.methodDeclsForFileTypes(semPkg, file)
|
|
123
130
|
relevantImportFiles := map[string]bool{sourcePath: true}
|
|
@@ -138,7 +145,9 @@ func (o *LoweringOwner) lowerFile(
|
|
|
138
145
|
importAliases := make(map[string]string)
|
|
139
146
|
importPaths := make(map[string]string)
|
|
140
147
|
importNames := make(map[string]string)
|
|
141
|
-
|
|
148
|
+
importObjects := make(map[*types.PkgName]string)
|
|
149
|
+
localRefs := o.analyzeLocalFileReferences(semPkg, file, sourcePath, associatedMethods, declFiles, outputNames)
|
|
150
|
+
reservedImportAliases := localRefs.reservedNames
|
|
142
151
|
seenImport := make(map[string]bool)
|
|
143
152
|
for idx, importFile := range semPkg.source.Syntax {
|
|
144
153
|
importSourcePath := sourceFilePath(semPkg, idx, importFile)
|
|
@@ -170,19 +179,19 @@ func (o *LoweringOwner) lowerFile(
|
|
|
170
179
|
importAliases[alias] = pkgName.Imported().Path()
|
|
171
180
|
importPaths[pkgName.Imported().Path()] = alias
|
|
172
181
|
importNames[name] = alias
|
|
182
|
+
importObjects[pkgName] = alias
|
|
173
183
|
loweredFile.imports = append(loweredFile.imports, loweredImport{
|
|
174
|
-
alias:
|
|
175
|
-
source:
|
|
184
|
+
alias: alias,
|
|
185
|
+
source: source,
|
|
186
|
+
sideEffect: true,
|
|
176
187
|
})
|
|
177
188
|
}
|
|
178
189
|
}
|
|
179
190
|
for importSourcePath := range relevantImportFiles {
|
|
180
191
|
o.addGeneratedTypeImports(model, semPkg, importSourcePath, loweredFile, importAliases, importPaths, reservedImportAliases, seenImport)
|
|
181
192
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
implicitImportPaths := make([]string, 0, len(implicitImports))
|
|
185
|
-
for pkgPath := range implicitImports {
|
|
193
|
+
implicitImportPaths := make([]string, 0, len(localRefs.implicitImports))
|
|
194
|
+
for pkgPath := range localRefs.implicitImports {
|
|
186
195
|
if pkgPath != "" && pkgPath != semPkg.pkgPath {
|
|
187
196
|
implicitImportPaths = append(implicitImportPaths, pkgPath)
|
|
188
197
|
}
|
|
@@ -191,15 +200,15 @@ func (o *LoweringOwner) lowerFile(
|
|
|
191
200
|
for _, pkgPath := range implicitImportPaths {
|
|
192
201
|
o.addGeneratedImportPath(model, pkgPath, loweredFile, importAliases, importPaths, reservedImportAliases, seenImport)
|
|
193
202
|
}
|
|
194
|
-
localImports := make([]loweredImport, 0, len(
|
|
203
|
+
localImports := make([]loweredImport, 0, len(localRefs.aliases))
|
|
195
204
|
seenLocalImport := make(map[string]bool)
|
|
196
|
-
for _, alias := range
|
|
205
|
+
for _, alias := range localRefs.aliases {
|
|
197
206
|
if seenLocalImport[alias] {
|
|
198
207
|
continue
|
|
199
208
|
}
|
|
200
209
|
seenLocalImport[alias] = true
|
|
201
|
-
source :=
|
|
202
|
-
localImports = append(localImports, loweredImport{alias: alias, source: source})
|
|
210
|
+
source := localRefs.aliasSources[alias]
|
|
211
|
+
localImports = append(localImports, loweredImport{alias: alias, source: source, sideEffect: true})
|
|
203
212
|
}
|
|
204
213
|
slices.SortFunc(localImports, func(a, b loweredImport) int {
|
|
205
214
|
return cmp.Compare(a.alias, b.alias)
|
|
@@ -213,15 +222,21 @@ func (o *LoweringOwner) lowerFile(
|
|
|
213
222
|
importAliases: importAliases,
|
|
214
223
|
importPaths: importPaths,
|
|
215
224
|
importNames: importNames,
|
|
225
|
+
importObjects: importObjects,
|
|
216
226
|
sourcePath: sourcePath,
|
|
217
|
-
localAliases:
|
|
227
|
+
localAliases: localRefs.aliases,
|
|
218
228
|
lazyPackageVars: lazyPackageVars,
|
|
219
229
|
tempNames: newTempNameOwner(),
|
|
220
230
|
topLevel: true,
|
|
221
231
|
}
|
|
222
232
|
var diagnostics []Diagnostic
|
|
233
|
+
var packageInitCalls []string
|
|
223
234
|
appendDecls := func(decls []loweredDecl) {
|
|
224
235
|
for _, decl := range decls {
|
|
236
|
+
if decl.packageInitCall != "" {
|
|
237
|
+
packageInitCalls = append(packageInitCalls, decl.packageInitCall)
|
|
238
|
+
continue
|
|
239
|
+
}
|
|
225
240
|
loweredFile.decls = append(loweredFile.decls, decl)
|
|
226
241
|
if decl.indexExport != "" {
|
|
227
242
|
loweredFile.exports = append(loweredFile.exports, decl.indexExport)
|
|
@@ -229,6 +244,9 @@ func (o *LoweringOwner) lowerFile(
|
|
|
229
244
|
if decl.typeIndexExport != "" {
|
|
230
245
|
loweredFile.typeExports = append(loweredFile.typeExports, decl.typeIndexExport)
|
|
231
246
|
}
|
|
247
|
+
if decl.sideEffect {
|
|
248
|
+
loweredFile.sideEffect = true
|
|
249
|
+
}
|
|
232
250
|
if decl.function != nil && decl.function.indexExported && decl.function.name != "main" {
|
|
233
251
|
loweredFile.exports = append(loweredFile.exports, decl.function.name)
|
|
234
252
|
}
|
|
@@ -252,6 +270,9 @@ func (o *LoweringOwner) lowerFile(
|
|
|
252
270
|
lowerDecl(decl)
|
|
253
271
|
}
|
|
254
272
|
}
|
|
273
|
+
for _, call := range packageInitCalls {
|
|
274
|
+
loweredFile.decls = append(loweredFile.decls, loweredDecl{code: "await " + call})
|
|
275
|
+
}
|
|
255
276
|
for _, decl := range loweredFile.decls {
|
|
256
277
|
if decl.function == nil || !decl.function.init {
|
|
257
278
|
continue
|
|
@@ -317,8 +338,9 @@ func (o *LoweringOwner) addGeneratedImportPath(
|
|
|
317
338
|
importAliases[alias] = pkgPath
|
|
318
339
|
importPaths[pkgPath] = alias
|
|
319
340
|
loweredFile.imports = append(loweredFile.imports, loweredImport{
|
|
320
|
-
alias:
|
|
321
|
-
source:
|
|
341
|
+
alias: alias,
|
|
342
|
+
source: source,
|
|
343
|
+
sideEffect: true,
|
|
322
344
|
})
|
|
323
345
|
}
|
|
324
346
|
|
|
@@ -351,36 +373,6 @@ func uniqueImportAlias(alias string, pkgPath string, importAliases map[string]st
|
|
|
351
373
|
}
|
|
352
374
|
}
|
|
353
375
|
|
|
354
|
-
func localDeclarationNames(semPkg *semanticPackage, file *ast.File, associatedMethods []*ast.FuncDecl) map[string]bool {
|
|
355
|
-
if semPkg == nil || semPkg.source == nil {
|
|
356
|
-
return nil
|
|
357
|
-
}
|
|
358
|
-
names := make(map[string]bool)
|
|
359
|
-
inspect := func(node ast.Node) bool {
|
|
360
|
-
ident, ok := node.(*ast.Ident)
|
|
361
|
-
if !ok {
|
|
362
|
-
return true
|
|
363
|
-
}
|
|
364
|
-
obj := semPkg.source.TypesInfo.Defs[ident]
|
|
365
|
-
if obj == nil {
|
|
366
|
-
return true
|
|
367
|
-
}
|
|
368
|
-
if _, ok := obj.(*types.PkgName); ok {
|
|
369
|
-
return true
|
|
370
|
-
}
|
|
371
|
-
name := safeIdentifier(obj.Name())
|
|
372
|
-
if name != "_" {
|
|
373
|
-
names[name] = true
|
|
374
|
-
}
|
|
375
|
-
return true
|
|
376
|
-
}
|
|
377
|
-
ast.Inspect(file, inspect)
|
|
378
|
-
for _, methodDecl := range associatedMethods {
|
|
379
|
-
ast.Inspect(methodDecl, inspect)
|
|
380
|
-
}
|
|
381
|
-
return names
|
|
382
|
-
}
|
|
383
|
-
|
|
384
376
|
func (o *LoweringOwner) methodDeclsForFileTypes(semPkg *semanticPackage, file *ast.File) []*ast.FuncDecl {
|
|
385
377
|
if semPkg == nil || semPkg.source == nil || file == nil {
|
|
386
378
|
return nil
|
|
@@ -433,27 +425,27 @@ func (o *LoweringOwner) methodDeclsForFileTypes(semPkg *semanticPackage, file *a
|
|
|
433
425
|
return methods
|
|
434
426
|
}
|
|
435
427
|
|
|
436
|
-
|
|
428
|
+
type localFileReferenceAnalysis struct {
|
|
429
|
+
reservedNames map[string]bool
|
|
430
|
+
aliases map[types.Object]string
|
|
431
|
+
aliasSources map[string]string
|
|
432
|
+
implicitImports map[string]bool
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
437
436
|
semPkg *semanticPackage,
|
|
438
437
|
file *ast.File,
|
|
439
438
|
sourcePath string,
|
|
440
439
|
associatedMethods []*ast.FuncDecl,
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
outputNames := make(map[string]string)
|
|
450
|
-
for idx, syntax := range semPkg.source.Syntax {
|
|
451
|
-
outputSourcePath := sourceFilePath(semPkg, idx, syntax)
|
|
452
|
-
outputNames[outputSourcePath] = sourceOutputName(outputSourcePath)
|
|
440
|
+
declFiles map[types.Object]string,
|
|
441
|
+
outputNames map[string]string,
|
|
442
|
+
) localFileReferenceAnalysis {
|
|
443
|
+
analysis := localFileReferenceAnalysis{
|
|
444
|
+
reservedNames: make(map[string]bool),
|
|
445
|
+
aliases: make(map[types.Object]string),
|
|
446
|
+
aliasSources: make(map[string]string),
|
|
447
|
+
implicitImports: make(map[string]bool),
|
|
453
448
|
}
|
|
454
|
-
aliases := make(map[types.Object]string)
|
|
455
|
-
aliasSources := make(map[string]string)
|
|
456
|
-
implicitImports := make(map[string]bool)
|
|
457
449
|
seenObjects := make(map[types.Object]bool)
|
|
458
450
|
seenTypes := make(map[types.Type]bool)
|
|
459
451
|
var addTypeDeps func(typ types.Type)
|
|
@@ -471,8 +463,8 @@ func (o *LoweringOwner) localFileAliases(
|
|
|
471
463
|
outputName := outputNames[declFile]
|
|
472
464
|
if outputName != "" {
|
|
473
465
|
alias := "__goscript_" + safeIdentifier(strings.TrimSuffix(outputName, ".gs.ts"))
|
|
474
|
-
aliases[obj] = alias
|
|
475
|
-
aliasSources[alias] = "./" + outputName
|
|
466
|
+
analysis.aliases[obj] = alias
|
|
467
|
+
analysis.aliasSources[alias] = "./" + outputName
|
|
476
468
|
}
|
|
477
469
|
}
|
|
478
470
|
switch typed := obj.(type) {
|
|
@@ -514,7 +506,7 @@ func (o *LoweringOwner) localFileAliases(
|
|
|
514
506
|
seenTypes[typ] = true
|
|
515
507
|
if alias, ok := typ.(*types.Alias); ok {
|
|
516
508
|
if obj := alias.Obj(); obj != nil && obj.Pkg() != nil && obj.Pkg().Path() != semPkg.pkgPath {
|
|
517
|
-
implicitImports[obj.Pkg().Path()] = true
|
|
509
|
+
analysis.implicitImports[obj.Pkg().Path()] = true
|
|
518
510
|
if args := alias.TypeArgs(); args != nil {
|
|
519
511
|
for t := range args.Types() {
|
|
520
512
|
addTypeDeps(t)
|
|
@@ -534,7 +526,7 @@ func (o *LoweringOwner) localFileAliases(
|
|
|
534
526
|
}
|
|
535
527
|
if named, ok := types.Unalias(typ).(*types.Named); ok {
|
|
536
528
|
if obj := named.Obj(); obj != nil && obj.Pkg() != nil && obj.Pkg().Path() != semPkg.pkgPath {
|
|
537
|
-
implicitImports[obj.Pkg().Path()] = true
|
|
529
|
+
analysis.implicitImports[obj.Pkg().Path()] = true
|
|
538
530
|
if args := named.TypeArgs(); args != nil {
|
|
539
531
|
for t := range args.Types() {
|
|
540
532
|
addTypeDeps(t)
|
|
@@ -591,11 +583,20 @@ func (o *LoweringOwner) localFileAliases(
|
|
|
591
583
|
inspect := func(node ast.Node) bool {
|
|
592
584
|
switch typed := node.(type) {
|
|
593
585
|
case *ast.Ident:
|
|
586
|
+
if obj := semPkg.source.TypesInfo.Defs[typed]; obj != nil {
|
|
587
|
+
if _, ok := obj.(*types.PkgName); !ok {
|
|
588
|
+
name := safeIdentifier(obj.Name())
|
|
589
|
+
if name != "_" {
|
|
590
|
+
analysis.reservedNames[name] = true
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
594
|
addObject(semPkg.source.TypesInfo.Uses[typed])
|
|
595
595
|
addTypeDeps(semPkg.source.TypesInfo.TypeOf(typed))
|
|
596
596
|
case *ast.SelectorExpr:
|
|
597
597
|
if selection := semPkg.source.TypesInfo.Selections[typed]; selection != nil {
|
|
598
598
|
addObject(selection.Obj())
|
|
599
|
+
addTypeDeps(selection.Obj().Type())
|
|
599
600
|
} else if obj := semPkg.source.TypesInfo.Uses[typed.Sel]; obj != nil {
|
|
600
601
|
addTypeDeps(obj.Type())
|
|
601
602
|
}
|
|
@@ -609,7 +610,7 @@ func (o *LoweringOwner) localFileAliases(
|
|
|
609
610
|
for _, methodDecl := range associatedMethods {
|
|
610
611
|
ast.Inspect(methodDecl, inspect)
|
|
611
612
|
}
|
|
612
|
-
return
|
|
613
|
+
return analysis
|
|
613
614
|
}
|
|
614
615
|
|
|
615
616
|
func safeIdentifier(value string) string {
|
|
@@ -668,12 +669,16 @@ type lowerFileContext struct {
|
|
|
668
669
|
importAliases map[string]string
|
|
669
670
|
importPaths map[string]string
|
|
670
671
|
importNames map[string]string
|
|
672
|
+
importObjects map[*types.PkgName]string
|
|
671
673
|
sourcePath string
|
|
672
674
|
localAliases map[types.Object]string
|
|
673
675
|
lazyPackageVars map[types.Object]bool
|
|
674
676
|
identAliases map[types.Object]string
|
|
677
|
+
identAliasRefs map[types.Object]bool
|
|
675
678
|
tempNames *tempNameOwner
|
|
676
679
|
signature *types.Signature
|
|
680
|
+
typeParams map[string]bool
|
|
681
|
+
staticTypeParams map[string]bool
|
|
677
682
|
asyncFunction bool
|
|
678
683
|
functionTypeDepth int
|
|
679
684
|
deferState *loweredDeferState
|
|
@@ -694,6 +699,30 @@ type tempNameOwner struct {
|
|
|
694
699
|
counters map[string]int
|
|
695
700
|
}
|
|
696
701
|
|
|
702
|
+
func (ctx lowerFileContext) canReferenceNamedType(named *types.Named) bool {
|
|
703
|
+
if named == nil || named.Obj() == nil {
|
|
704
|
+
return true
|
|
705
|
+
}
|
|
706
|
+
return ctx.canReferenceObjectPackage(named.Obj())
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
func (ctx lowerFileContext) canReferenceObjectPackage(obj types.Object) bool {
|
|
710
|
+
if obj == nil || obj.Pkg() == nil || ctx.semPkg == nil {
|
|
711
|
+
return true
|
|
712
|
+
}
|
|
713
|
+
pkgPath := obj.Pkg().Path()
|
|
714
|
+
if pkgPath == "" || pkgPath == ctx.semPkg.pkgPath {
|
|
715
|
+
return true
|
|
716
|
+
}
|
|
717
|
+
if ctx.importPaths[pkgPath] != "" {
|
|
718
|
+
return true
|
|
719
|
+
}
|
|
720
|
+
if ctx.localAliases[obj] != "" {
|
|
721
|
+
return true
|
|
722
|
+
}
|
|
723
|
+
return false
|
|
724
|
+
}
|
|
725
|
+
|
|
697
726
|
func newTempNameOwner() *tempNameOwner {
|
|
698
727
|
return &tempNameOwner{counters: make(map[string]int)}
|
|
699
728
|
}
|
|
@@ -720,6 +749,20 @@ func (ctx lowerFileContext) withIdentAliases(aliases map[types.Object]string) lo
|
|
|
720
749
|
return ctx
|
|
721
750
|
}
|
|
722
751
|
|
|
752
|
+
func (ctx lowerFileContext) withIdentRefAliases(aliases map[types.Object]string) lowerFileContext {
|
|
753
|
+
if len(aliases) == 0 {
|
|
754
|
+
return ctx
|
|
755
|
+
}
|
|
756
|
+
ctx = ctx.withIdentAliases(aliases)
|
|
757
|
+
refs := make(map[types.Object]bool, len(ctx.identAliasRefs)+len(aliases))
|
|
758
|
+
maps.Copy(refs, ctx.identAliasRefs)
|
|
759
|
+
for obj := range aliases {
|
|
760
|
+
refs[obj] = true
|
|
761
|
+
}
|
|
762
|
+
ctx.identAliasRefs = refs
|
|
763
|
+
return ctx
|
|
764
|
+
}
|
|
765
|
+
|
|
723
766
|
func (o *tempNameOwner) next(prefix string) string {
|
|
724
767
|
idx := o.counters[prefix]
|
|
725
768
|
o.counters[prefix] = idx + 1
|
|
@@ -838,9 +881,21 @@ func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([
|
|
|
838
881
|
decls = append(decls, loweredDecl{code: code, indexExport: indexExport})
|
|
839
882
|
if lazy {
|
|
840
883
|
getterName := packageVarGetterName(name.Name)
|
|
841
|
-
getterCode := "export function " + getterName + "(): " + variableType + " {\n\t"
|
|
842
|
-
|
|
843
|
-
|
|
884
|
+
getterCode := "export function " + getterName + "(): " + variableType + " {\n\t"
|
|
885
|
+
if strings.Contains(value, "await ") {
|
|
886
|
+
initName := packageVarInitName(name.Name)
|
|
887
|
+
initCode := "async function " + initName + "(): globalThis.Promise<void> {\n\t" +
|
|
888
|
+
"if (((" + declName + ") as any) === undefined) {\n\t\t" +
|
|
889
|
+
declName + " = " + value + "\n\t}\n}"
|
|
890
|
+
decls = append(decls, loweredDecl{code: initCode})
|
|
891
|
+
decls = append(decls, loweredDecl{packageInitCall: initName + "()"})
|
|
892
|
+
getterCode += "if (((" + declName + ") as any) === undefined) {\n\t\t" +
|
|
893
|
+
"throw new Error(" + strconv.Quote("goscript package variable "+name.Name+" read before initialization") + ")\n\t}\n"
|
|
894
|
+
} else {
|
|
895
|
+
getterCode += "if (((" + declName + ") as any) === undefined) {\n\t\t" +
|
|
896
|
+
declName + " = " + value + "\n\t}\n"
|
|
897
|
+
}
|
|
898
|
+
getterCode += "\treturn " + declName + "\n}"
|
|
844
899
|
getterIndexExport := ""
|
|
845
900
|
if ast.IsExported(name.Name) {
|
|
846
901
|
getterIndexExport = getterName
|
|
@@ -924,7 +979,7 @@ func initializerMayHaveRuntimeEffects(ctx lowerFileContext, expr ast.Expr) bool
|
|
|
924
979
|
return hasEffects
|
|
925
980
|
}
|
|
926
981
|
|
|
927
|
-
func (
|
|
982
|
+
func packageDeclFiles(semPkg *semanticPackage) map[types.Object]string {
|
|
928
983
|
if semPkg == nil || semPkg.source == nil {
|
|
929
984
|
return nil
|
|
930
985
|
}
|
|
@@ -934,6 +989,25 @@ func (o *LoweringOwner) lazyPackageVars(semPkg *semanticPackage) map[types.Objec
|
|
|
934
989
|
declFiles[decl.object] = decl.position.file
|
|
935
990
|
}
|
|
936
991
|
}
|
|
992
|
+
return declFiles
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
func packageOutputNames(semPkg *semanticPackage) map[string]string {
|
|
996
|
+
if semPkg == nil || semPkg.source == nil {
|
|
997
|
+
return nil
|
|
998
|
+
}
|
|
999
|
+
outputNames := make(map[string]string, len(semPkg.source.Syntax))
|
|
1000
|
+
for idx, syntax := range semPkg.source.Syntax {
|
|
1001
|
+
outputSourcePath := sourceFilePath(semPkg, idx, syntax)
|
|
1002
|
+
outputNames[outputSourcePath] = sourceOutputName(outputSourcePath)
|
|
1003
|
+
}
|
|
1004
|
+
return outputNames
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
func (o *LoweringOwner) lazyPackageVars(semPkg *semanticPackage, declFiles map[types.Object]string) map[types.Object]bool {
|
|
1008
|
+
if semPkg == nil || semPkg.source == nil {
|
|
1009
|
+
return nil
|
|
1010
|
+
}
|
|
937
1011
|
varOrder := make(map[types.Object]int)
|
|
938
1012
|
for idx, obj := range semPkg.initOrder {
|
|
939
1013
|
varOrder[obj] = idx
|
|
@@ -956,6 +1030,11 @@ func (o *LoweringOwner) lazyPackageVars(semPkg *semanticPackage) map[types.Objec
|
|
|
956
1030
|
if obj == nil {
|
|
957
1031
|
continue
|
|
958
1032
|
}
|
|
1033
|
+
if valueIdx < len(valueSpec.Values) &&
|
|
1034
|
+
initializerReferencesLaterPackageVar(semPkg, varOrder, obj, valueSpec.Values[valueIdx]) {
|
|
1035
|
+
lazy[obj] = true
|
|
1036
|
+
continue
|
|
1037
|
+
}
|
|
959
1038
|
if valueIdx < len(valueSpec.Values) &&
|
|
960
1039
|
initializerReferencesOtherFileObject(semPkg, declFiles, sourcePath, valueSpec.Values[valueIdx]) {
|
|
961
1040
|
lazy[obj] = true
|
|
@@ -977,6 +1056,41 @@ func (o *LoweringOwner) lazyPackageVars(semPkg *semanticPackage) map[types.Objec
|
|
|
977
1056
|
return lazy
|
|
978
1057
|
}
|
|
979
1058
|
|
|
1059
|
+
func initializerReferencesLaterPackageVar(
|
|
1060
|
+
semPkg *semanticPackage,
|
|
1061
|
+
varOrder map[types.Object]int,
|
|
1062
|
+
current types.Object,
|
|
1063
|
+
expr ast.Expr,
|
|
1064
|
+
) bool {
|
|
1065
|
+
currentIdx, ok := varOrder[current]
|
|
1066
|
+
if !ok {
|
|
1067
|
+
return false
|
|
1068
|
+
}
|
|
1069
|
+
references := false
|
|
1070
|
+
ast.Inspect(expr, func(node ast.Node) bool {
|
|
1071
|
+
if references {
|
|
1072
|
+
return false
|
|
1073
|
+
}
|
|
1074
|
+
if _, ok := node.(*ast.FuncLit); ok {
|
|
1075
|
+
return false
|
|
1076
|
+
}
|
|
1077
|
+
ident, ok := node.(*ast.Ident)
|
|
1078
|
+
if !ok {
|
|
1079
|
+
return true
|
|
1080
|
+
}
|
|
1081
|
+
obj, ok := semPkg.source.TypesInfo.Uses[ident].(*types.Var)
|
|
1082
|
+
if !ok || obj.Pkg() == nil || obj.Pkg().Path() != semPkg.pkgPath {
|
|
1083
|
+
return true
|
|
1084
|
+
}
|
|
1085
|
+
if idx, ok := varOrder[obj]; ok && idx > currentIdx {
|
|
1086
|
+
references = true
|
|
1087
|
+
return false
|
|
1088
|
+
}
|
|
1089
|
+
return true
|
|
1090
|
+
})
|
|
1091
|
+
return references
|
|
1092
|
+
}
|
|
1093
|
+
|
|
980
1094
|
func initializerCallsFunctionReferencingLaterPackageVar(
|
|
981
1095
|
semPkg *semanticPackage,
|
|
982
1096
|
varOrder map[types.Object]int,
|
|
@@ -1223,7 +1337,7 @@ func lowerConstantValue(value constant.Value) (string, bool) {
|
|
|
1223
1337
|
case constant.Bool:
|
|
1224
1338
|
return strconv.FormatBool(constant.BoolVal(value)), true
|
|
1225
1339
|
case constant.String:
|
|
1226
|
-
return
|
|
1340
|
+
return lowerGoStringLiteral(constant.StringVal(value)), true
|
|
1227
1341
|
case constant.Int:
|
|
1228
1342
|
if intValue, ok := constant.Int64Val(value); ok {
|
|
1229
1343
|
return strconv.FormatInt(intValue, 10), true
|
|
@@ -1237,7 +1351,7 @@ func lowerConstantValue(value constant.Value) (string, bool) {
|
|
|
1237
1351
|
case constant.Complex:
|
|
1238
1352
|
real := constant.Real(value).ExactString()
|
|
1239
1353
|
imag := constant.Imag(value).ExactString()
|
|
1240
|
-
return "(
|
|
1354
|
+
return "$.complex(" + real + ", " + imag + ")", true
|
|
1241
1355
|
default:
|
|
1242
1356
|
return "", false
|
|
1243
1357
|
}
|
|
@@ -1333,6 +1447,13 @@ func byteSliceLiteral(data []byte) string {
|
|
|
1333
1447
|
return "new Uint8Array([" + strings.Join(values, ", ") + "])"
|
|
1334
1448
|
}
|
|
1335
1449
|
|
|
1450
|
+
func lowerGoStringLiteral(value string) string {
|
|
1451
|
+
if utf8.ValidString(value) {
|
|
1452
|
+
return strconv.Quote(value)
|
|
1453
|
+
}
|
|
1454
|
+
return "$.bytesToString(" + byteSliceLiteral([]byte(value)) + ")"
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1336
1457
|
func (o *LoweringOwner) lowerTypeSpec(ctx lowerFileContext, spec *ast.TypeSpec) (loweredDecl, []Diagnostic) {
|
|
1337
1458
|
obj, _ := ctx.semPkg.source.TypesInfo.Defs[spec.Name].(*types.TypeName)
|
|
1338
1459
|
if obj == nil {
|
|
@@ -1396,7 +1517,7 @@ func (o *LoweringOwner) lowerInterfaceType(ctx lowerFileContext, semType *semant
|
|
|
1396
1517
|
code = code + "\n\n" + o.runtimeOwner.QualifiedHelper(RuntimeHelperRegisterInterfaceType) +
|
|
1397
1518
|
"(\n\t" + strconv.Quote(runtimeNamedTypeName(semType.named)) +
|
|
1398
1519
|
",\n\tnull,\n\t" + o.runtimeMethodSignatures(iface) + "\n)"
|
|
1399
|
-
return loweredDecl{code: code, typeIndexExport: typeIndexExport}
|
|
1520
|
+
return loweredDecl{code: code, typeIndexExport: typeIndexExport, sideEffect: true}
|
|
1400
1521
|
}
|
|
1401
1522
|
|
|
1402
1523
|
func (o *LoweringOwner) tsInterfaceType(ctx lowerFileContext, iface *types.Interface) string {
|
|
@@ -1407,7 +1528,7 @@ func (o *LoweringOwner) tsInterfaceType(ctx lowerFileContext, iface *types.Inter
|
|
|
1407
1528
|
for method := range iface.Methods() {
|
|
1408
1529
|
methods = append(methods, o.tsMethodSignature(ctx, method))
|
|
1409
1530
|
}
|
|
1410
|
-
return "
|
|
1531
|
+
return "{\n\t" + strings.Join(methods, "\n\t") + "\n}"
|
|
1411
1532
|
}
|
|
1412
1533
|
|
|
1413
1534
|
func (o *LoweringOwner) tsMethodSignature(ctx lowerFileContext, method *types.Func) string {
|
|
@@ -1417,7 +1538,7 @@ func (o *LoweringOwner) tsMethodSignature(ctx lowerFileContext, method *types.Fu
|
|
|
1417
1538
|
}
|
|
1418
1539
|
async := o.functionAsync(ctx, method)
|
|
1419
1540
|
return method.Name() + "(" + o.tsSignatureParamsFor(ctx, signature, async) + "): " +
|
|
1420
|
-
|
|
1541
|
+
asyncCompatibleMethodResultType(o.tsSignatureResultFor(ctx, signature), async)
|
|
1421
1542
|
}
|
|
1422
1543
|
|
|
1423
1544
|
func (o *LoweringOwner) runtimeMethodSignatures(iface *types.Interface) string {
|
|
@@ -1483,6 +1604,10 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
1483
1604
|
cloneMethod: "clone",
|
|
1484
1605
|
}
|
|
1485
1606
|
for idx, field := range semType.fields {
|
|
1607
|
+
structValue := isStructValueType(field.typ)
|
|
1608
|
+
if named := namedStructType(field.typ); named != nil && crossPackageUnexportedNamedType(ctx, named) {
|
|
1609
|
+
structValue = false
|
|
1610
|
+
}
|
|
1486
1611
|
fieldName := tsStructFieldName(field.name, idx)
|
|
1487
1612
|
runtimeName := ""
|
|
1488
1613
|
if fieldName != field.name {
|
|
@@ -1496,11 +1621,18 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
1496
1621
|
runtimeType: o.runtimeTypeInfoExpr(field.typ),
|
|
1497
1622
|
doc: field.doc,
|
|
1498
1623
|
tag: field.tag,
|
|
1499
|
-
structValue:
|
|
1624
|
+
structValue: structValue,
|
|
1625
|
+
arrayValue: isArrayType(field.typ),
|
|
1500
1626
|
})
|
|
1501
1627
|
}
|
|
1502
1628
|
|
|
1503
1629
|
methodDecls := o.methodDeclsForType(ctx, semType.named)
|
|
1630
|
+
explicitMethods := make(map[string]bool, len(methodDecls))
|
|
1631
|
+
for _, methodDecl := range methodDecls {
|
|
1632
|
+
if methodDecl != nil {
|
|
1633
|
+
explicitMethods[methodDecl.Name.Name] = true
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1504
1636
|
var diagnostics []Diagnostic
|
|
1505
1637
|
for _, methodDecl := range methodDecls {
|
|
1506
1638
|
method, methodDiagnostics := o.lowerFuncDecl(ctx, methodDecl)
|
|
@@ -1512,9 +1644,121 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
1512
1644
|
lowered.methods = append(lowered.methods, *method)
|
|
1513
1645
|
}
|
|
1514
1646
|
}
|
|
1647
|
+
for _, field := range semType.fields {
|
|
1648
|
+
methods := o.lowerEmbeddedMethodForwarders(ctx, field, explicitMethods)
|
|
1649
|
+
lowered.methods = append(lowered.methods, methods...)
|
|
1650
|
+
}
|
|
1515
1651
|
return lowered, diagnostics
|
|
1516
1652
|
}
|
|
1517
1653
|
|
|
1654
|
+
func (o *LoweringOwner) lowerEmbeddedMethodForwarders(
|
|
1655
|
+
ctx lowerFileContext,
|
|
1656
|
+
field semanticField,
|
|
1657
|
+
explicitMethods map[string]bool,
|
|
1658
|
+
) []loweredFunction {
|
|
1659
|
+
if !field.embedded {
|
|
1660
|
+
return nil
|
|
1661
|
+
}
|
|
1662
|
+
methodSetType := field.typ
|
|
1663
|
+
if named := namedStructType(field.typ); named != nil {
|
|
1664
|
+
methodSetType = types.NewPointer(field.typ)
|
|
1665
|
+
} else if pointerToNamedStructType(field.typ) != nil {
|
|
1666
|
+
methodSetType = field.typ
|
|
1667
|
+
} else if _, ok := types.Unalias(field.typ).Underlying().(*types.Interface); !ok {
|
|
1668
|
+
return nil
|
|
1669
|
+
}
|
|
1670
|
+
methodSet := types.NewMethodSet(methodSetType)
|
|
1671
|
+
if methodSet.Len() == 0 {
|
|
1672
|
+
return nil
|
|
1673
|
+
}
|
|
1674
|
+
var methods []loweredFunction
|
|
1675
|
+
for selection := range methodSet.Methods() {
|
|
1676
|
+
method, _ := selection.Obj().(*types.Func)
|
|
1677
|
+
if method == nil || explicitMethods[method.Name()] {
|
|
1678
|
+
continue
|
|
1679
|
+
}
|
|
1680
|
+
if !ast.IsExported(method.Name()) && method.Pkg() != nil && method.Pkg().Path() != ctx.semPkg.pkgPath {
|
|
1681
|
+
continue
|
|
1682
|
+
}
|
|
1683
|
+
signature, _ := method.Type().(*types.Signature)
|
|
1684
|
+
if signature == nil {
|
|
1685
|
+
continue
|
|
1686
|
+
}
|
|
1687
|
+
async := o.functionAsync(ctx, method)
|
|
1688
|
+
targetType := o.tsEmbeddedForwarderTargetType(ctx, field.typ)
|
|
1689
|
+
lowered := loweredFunction{
|
|
1690
|
+
async: async,
|
|
1691
|
+
name: methodMemberName(method.Name()),
|
|
1692
|
+
runtimeName: method.Name(),
|
|
1693
|
+
result: asyncResultType("any", async),
|
|
1694
|
+
deferState: &loweredDeferState{},
|
|
1695
|
+
}
|
|
1696
|
+
args := make([]string, 0, signature.Params().Len())
|
|
1697
|
+
for idx := range signature.Params().Len() {
|
|
1698
|
+
param := signature.Params().At(idx)
|
|
1699
|
+
name := safeParamName(param, idx)
|
|
1700
|
+
args = append(args, name)
|
|
1701
|
+
lowered.params = append(lowered.params, loweredParam{name: name, typ: "any"})
|
|
1702
|
+
}
|
|
1703
|
+
target := o.embeddedForwarderTargetExpr(ctx, field, selection, targetType)
|
|
1704
|
+
call := target + "." + method.Name() + "(" + strings.Join(args, ", ") + ")"
|
|
1705
|
+
if async {
|
|
1706
|
+
call = "await " + call
|
|
1707
|
+
}
|
|
1708
|
+
lowered.body = []loweredStmt{{text: "return " + call}}
|
|
1709
|
+
methods = append(methods, lowered)
|
|
1710
|
+
explicitMethods[method.Name()] = true
|
|
1711
|
+
}
|
|
1712
|
+
return methods
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
func (o *LoweringOwner) embeddedForwarderTargetExpr(
|
|
1716
|
+
ctx lowerFileContext,
|
|
1717
|
+
field semanticField,
|
|
1718
|
+
selection *types.Selection,
|
|
1719
|
+
targetType string,
|
|
1720
|
+
) string {
|
|
1721
|
+
pointerValue := o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue)
|
|
1722
|
+
expr := pointerValue + "<" + targetType + ">(this." + tsStructFieldName(field.name, 0) + ")"
|
|
1723
|
+
if selection == nil || len(selection.Index()) <= 1 {
|
|
1724
|
+
return expr
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
typ := field.typ
|
|
1728
|
+
for _, index := range selection.Index()[:len(selection.Index())-1] {
|
|
1729
|
+
structType, ok := types.Unalias(derefPointerType(typ)).Underlying().(*types.Struct)
|
|
1730
|
+
if !ok || index < 0 || index >= structType.NumFields() {
|
|
1731
|
+
return expr
|
|
1732
|
+
}
|
|
1733
|
+
field := structType.Field(index)
|
|
1734
|
+
expr += "." + tsStructFieldName(field.Name(), index)
|
|
1735
|
+
typ = field.Type()
|
|
1736
|
+
expr = o.embeddedForwarderSelectableExpr(ctx, typ, expr)
|
|
1737
|
+
}
|
|
1738
|
+
return expr
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
func (o *LoweringOwner) embeddedForwarderSelectableExpr(ctx lowerFileContext, typ types.Type, expr string) string {
|
|
1742
|
+
pointerValue := o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue)
|
|
1743
|
+
if named := pointerToNamedStructType(typ); named != nil {
|
|
1744
|
+
return pointerValue + "<any>(" + expr + ")"
|
|
1745
|
+
}
|
|
1746
|
+
if _, ok := types.Unalias(typ).Underlying().(*types.Interface); ok {
|
|
1747
|
+
return pointerValue + "<any>(" + expr + ")"
|
|
1748
|
+
}
|
|
1749
|
+
return expr
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
func (o *LoweringOwner) tsEmbeddedForwarderTargetType(ctx lowerFileContext, typ types.Type) string {
|
|
1753
|
+
if named := pointerToNamedStructType(typ); named != nil {
|
|
1754
|
+
return o.namedTypeExpr(ctx, named)
|
|
1755
|
+
}
|
|
1756
|
+
if named := namedStructType(typ); named != nil {
|
|
1757
|
+
return o.namedTypeExpr(ctx, named)
|
|
1758
|
+
}
|
|
1759
|
+
return "Exclude<" + o.tsStructFieldTypeFor(ctx, typ) + ", null>"
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1518
1762
|
func (o *LoweringOwner) methodDeclsForType(ctx lowerFileContext, named *types.Named) []*ast.FuncDecl {
|
|
1519
1763
|
if named == nil {
|
|
1520
1764
|
return nil
|
|
@@ -1574,7 +1818,8 @@ func (o *LoweringOwner) lowerNamedReceiverMethodDecl(
|
|
|
1574
1818
|
return nil, nil
|
|
1575
1819
|
}
|
|
1576
1820
|
async := o.functionAsync(ctx, fnObj)
|
|
1577
|
-
|
|
1821
|
+
functionCtx := ctx.withSignature(signature)
|
|
1822
|
+
resultCtx := functionCtx.withAsyncFunction(async)
|
|
1578
1823
|
result := o.tsSignatureResultFor(resultCtx, signature)
|
|
1579
1824
|
receiverName := "recv"
|
|
1580
1825
|
if len(decl.Recv.List) != 0 && len(decl.Recv.List[0].Names) != 0 {
|
|
@@ -1634,7 +1879,11 @@ func (o *LoweringOwner) lowerFuncDecl(ctx lowerFileContext, decl *ast.FuncDecl)
|
|
|
1634
1879
|
return nil, nil
|
|
1635
1880
|
}
|
|
1636
1881
|
async := o.functionAsync(ctx, fnObj)
|
|
1637
|
-
|
|
1882
|
+
if decl.Name.Name == "main" {
|
|
1883
|
+
async = true
|
|
1884
|
+
}
|
|
1885
|
+
functionCtx := ctx.withSignature(signature)
|
|
1886
|
+
resultCtx := functionCtx.withAsyncFunction(async)
|
|
1638
1887
|
result := o.tsSignatureResultFor(resultCtx, signature)
|
|
1639
1888
|
deferState := &loweredDeferState{}
|
|
1640
1889
|
name := safeIdentifier(decl.Name.Name)
|
|
@@ -1659,9 +1908,10 @@ func (o *LoweringOwner) lowerFuncDecl(ctx lowerFileContext, decl *ast.FuncDecl)
|
|
|
1659
1908
|
runtimeName: runtimeName,
|
|
1660
1909
|
result: asyncResultType(result, async),
|
|
1661
1910
|
deferState: deferState,
|
|
1662
|
-
namedResults: o.lowerNamedResults(
|
|
1911
|
+
namedResults: o.lowerNamedResults(functionCtx, signature),
|
|
1663
1912
|
}
|
|
1664
1913
|
if signature.TypeParams() != nil && signature.TypeParams().Len() != 0 {
|
|
1914
|
+
lowered.typeParams = signatureTypeParamNames(signature)
|
|
1665
1915
|
lowered.params = append(lowered.params, loweredParam{
|
|
1666
1916
|
name: "__typeArgs",
|
|
1667
1917
|
typ: "$.GenericTypeArgs | undefined",
|
|
@@ -1684,24 +1934,20 @@ func (o *LoweringOwner) lowerFuncDecl(ctx lowerFileContext, decl *ast.FuncDecl)
|
|
|
1684
1934
|
lowered.receiverValue = o.runtimeOwner.QualifiedHelper(RuntimeHelperVarRef) + "(this)"
|
|
1685
1935
|
}
|
|
1686
1936
|
}
|
|
1687
|
-
if decl.Name.Name == "main" {
|
|
1688
|
-
lowered.async = true
|
|
1689
|
-
lowered.result = asyncResultType(o.tsSignatureResultFor(ctx.withAsyncFunction(true), signature), true)
|
|
1690
|
-
}
|
|
1691
1937
|
for idx := range signature.Params().Len() {
|
|
1692
1938
|
param := signature.Params().At(idx)
|
|
1693
|
-
lowered.params, lowered.paramBindings = o.appendLoweredParam(
|
|
1939
|
+
lowered.params, lowered.paramBindings = o.appendLoweredParam(functionCtx, lowered.params, lowered.paramBindings, param, idx, decl.Body == nil || async)
|
|
1694
1940
|
}
|
|
1695
1941
|
if decl.Body != nil {
|
|
1696
|
-
body, diagnostics := o.lowerBlock(
|
|
1942
|
+
body, diagnostics := o.lowerBlock(functionCtx.withAsyncFunction(async).withDeferState(deferState), decl.Body)
|
|
1697
1943
|
lowered.body = body
|
|
1698
1944
|
if deferState.async && !lowered.async {
|
|
1699
1945
|
lowered.async = true
|
|
1700
|
-
lowered.result = asyncResultType(o.tsSignatureResultFor(
|
|
1946
|
+
lowered.result = asyncResultType(o.tsSignatureResultFor(functionCtx.withAsyncFunction(true), signature), true)
|
|
1701
1947
|
}
|
|
1702
1948
|
return lowered, diagnostics
|
|
1703
1949
|
}
|
|
1704
|
-
if zeroReturn, ok := o.lowerBodylessReturnStmt(
|
|
1950
|
+
if zeroReturn, ok := o.lowerBodylessReturnStmt(functionCtx, signature); ok {
|
|
1705
1951
|
lowered.body = []loweredStmt{{text: zeroReturn}}
|
|
1706
1952
|
}
|
|
1707
1953
|
return lowered, nil
|
|
@@ -1754,6 +2000,54 @@ func rangeBindingAssignedInBody(ctx lowerFileContext, expr ast.Expr, body *ast.B
|
|
|
1754
2000
|
return objectAssignedInBlock(ctx, obj, body)
|
|
1755
2001
|
}
|
|
1756
2002
|
|
|
2003
|
+
func (o *LoweringOwner) lowerMapRangeBinding(
|
|
2004
|
+
ctx lowerFileContext,
|
|
2005
|
+
expr ast.Expr,
|
|
2006
|
+
name string,
|
|
2007
|
+
fallback string,
|
|
2008
|
+
tempPrefix string,
|
|
2009
|
+
declare bool,
|
|
2010
|
+
) (string, []loweredStmt, []Diagnostic) {
|
|
2011
|
+
if expr == nil {
|
|
2012
|
+
return fallback, nil, nil
|
|
2013
|
+
}
|
|
2014
|
+
if ident, ok := expr.(*ast.Ident); ok && ident.Name == "_" {
|
|
2015
|
+
return fallback, nil, nil
|
|
2016
|
+
}
|
|
2017
|
+
if declare {
|
|
2018
|
+
obj := rangeBindingObject(ctx, expr)
|
|
2019
|
+
if name == "" || obj == nil || !ctx.model.needsVarRef[obj] {
|
|
2020
|
+
if name != "" {
|
|
2021
|
+
return name, nil, nil
|
|
2022
|
+
}
|
|
2023
|
+
return fallback, nil, nil
|
|
2024
|
+
}
|
|
2025
|
+
rawName := ctx.tempName(tempPrefix)
|
|
2026
|
+
value := rawName
|
|
2027
|
+
if isStructValueType(obj.Type()) {
|
|
2028
|
+
value = o.lowerStructClone(value)
|
|
2029
|
+
}
|
|
2030
|
+
return rawName, []loweredStmt{{
|
|
2031
|
+
text: "let " + name + ": " + o.tsVariableTypeFor(ctx, obj.Type(), true) + " = " +
|
|
2032
|
+
o.runtimeOwner.QualifiedHelper(RuntimeHelperVarRef) + "(" + value + ")",
|
|
2033
|
+
}}, nil
|
|
2034
|
+
}
|
|
2035
|
+
rawName := ctx.tempName(tempPrefix)
|
|
2036
|
+
left, diagnostics := o.lowerAssignmentTarget(ctx, expr, false)
|
|
2037
|
+
return rawName, []loweredStmt{{text: left + " = " + rawName}}, diagnostics
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2040
|
+
func rangeBindingObject(ctx lowerFileContext, expr ast.Expr) types.Object {
|
|
2041
|
+
ident, ok := expr.(*ast.Ident)
|
|
2042
|
+
if !ok || ident.Name == "_" || ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
2043
|
+
return nil
|
|
2044
|
+
}
|
|
2045
|
+
if obj := ctx.semPkg.source.TypesInfo.Defs[ident]; obj != nil {
|
|
2046
|
+
return obj
|
|
2047
|
+
}
|
|
2048
|
+
return ctx.semPkg.source.TypesInfo.Uses[ident]
|
|
2049
|
+
}
|
|
2050
|
+
|
|
1757
2051
|
func expressionUsesObject(ctx lowerFileContext, expr ast.Expr, obj types.Object) bool {
|
|
1758
2052
|
if expr == nil || obj == nil || ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
1759
2053
|
return false
|
|
@@ -1803,6 +2097,20 @@ func (o *LoweringOwner) appendLoweredParam(
|
|
|
1803
2097
|
|
|
1804
2098
|
func (ctx lowerFileContext) withSignature(signature *types.Signature) lowerFileContext {
|
|
1805
2099
|
ctx.signature = signature
|
|
2100
|
+
if signature != nil && signature.TypeParams() != nil && signature.TypeParams().Len() != 0 {
|
|
2101
|
+
next := make(map[string]bool, len(ctx.typeParams)+signature.TypeParams().Len())
|
|
2102
|
+
maps.Copy(next, ctx.typeParams)
|
|
2103
|
+
nextStatic := make(map[string]bool, len(ctx.staticTypeParams)+signature.TypeParams().Len())
|
|
2104
|
+
maps.Copy(nextStatic, ctx.staticTypeParams)
|
|
2105
|
+
for typeParam := range signature.TypeParams().TypeParams() {
|
|
2106
|
+
next[typeParam.Obj().Name()] = true
|
|
2107
|
+
if signatureUsesTypeParamAsSliceElem(signature, typeParam) {
|
|
2108
|
+
nextStatic[typeParam.Obj().Name()] = true
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
ctx.typeParams = next
|
|
2112
|
+
ctx.staticTypeParams = nextStatic
|
|
2113
|
+
}
|
|
1806
2114
|
return ctx
|
|
1807
2115
|
}
|
|
1808
2116
|
|
|
@@ -1852,7 +2160,18 @@ func (ctx lowerFileContext) withoutRangeBreak() lowerFileContext {
|
|
|
1852
2160
|
}
|
|
1853
2161
|
|
|
1854
2162
|
func (ctx lowerFileContext) withGotoLabels(labels map[string]bool) lowerFileContext {
|
|
1855
|
-
ctx.gotoLabels
|
|
2163
|
+
if len(ctx.gotoLabels) == 0 {
|
|
2164
|
+
ctx.gotoLabels = labels
|
|
2165
|
+
return ctx
|
|
2166
|
+
}
|
|
2167
|
+
merged := make(map[string]bool, len(ctx.gotoLabels)+len(labels))
|
|
2168
|
+
for label := range ctx.gotoLabels {
|
|
2169
|
+
merged[label] = true
|
|
2170
|
+
}
|
|
2171
|
+
for label := range labels {
|
|
2172
|
+
merged[label] = true
|
|
2173
|
+
}
|
|
2174
|
+
ctx.gotoLabels = merged
|
|
1856
2175
|
return ctx
|
|
1857
2176
|
}
|
|
1858
2177
|
|
|
@@ -1884,6 +2203,11 @@ func (ctx lowerFileContext) withLoopLabel(label string) lowerFileContext {
|
|
|
1884
2203
|
return ctx
|
|
1885
2204
|
}
|
|
1886
2205
|
|
|
2206
|
+
func (ctx lowerFileContext) withoutLoopLabel() lowerFileContext {
|
|
2207
|
+
ctx.loopLabel = ""
|
|
2208
|
+
return ctx
|
|
2209
|
+
}
|
|
2210
|
+
|
|
1887
2211
|
func (ctx lowerFileContext) withSwitchBreak() lowerFileContext {
|
|
1888
2212
|
ctx.switchBreak = true
|
|
1889
2213
|
return ctx
|
|
@@ -1999,6 +2323,22 @@ func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
1999
2323
|
expr, diagnostics := o.lowerPointerStorageExpr(ctx, star.X)
|
|
2000
2324
|
return []loweredStmt{{text: expr + typed.Tok.String()}}, diagnostics
|
|
2001
2325
|
}
|
|
2326
|
+
if index, ok := unwrapParenExpr(typed.X).(*ast.IndexExpr); ok && isMapType(ctx.semPkg.source.TypesInfo.TypeOf(index.X)) {
|
|
2327
|
+
right := "1"
|
|
2328
|
+
tok := token.ADD_ASSIGN
|
|
2329
|
+
if typed.Tok == token.DEC {
|
|
2330
|
+
tok = token.SUB_ASSIGN
|
|
2331
|
+
}
|
|
2332
|
+
return o.lowerMapIndexUpdateStmts(ctx, index, tok, right, ctx.semPkg.source.TypesInfo.TypeOf(typed.X))
|
|
2333
|
+
}
|
|
2334
|
+
if setter, ok := o.packageVarSetterForAssignment(ctx, typed.X); ok {
|
|
2335
|
+
expr, diagnostics := o.lowerExpr(ctx, typed.X)
|
|
2336
|
+
op := "+"
|
|
2337
|
+
if typed.Tok == token.DEC {
|
|
2338
|
+
op = "-"
|
|
2339
|
+
}
|
|
2340
|
+
return []loweredStmt{{text: setter + "(" + expr + " " + op + " 1)"}}, diagnostics
|
|
2341
|
+
}
|
|
2002
2342
|
expr, diagnostics := o.lowerExpr(ctx, typed.X)
|
|
2003
2343
|
return []loweredStmt{{text: expr + typed.Tok.String()}}, diagnostics
|
|
2004
2344
|
case *ast.BranchStmt:
|
|
@@ -2068,6 +2408,10 @@ func packageVarGetterName(name string) string {
|
|
|
2068
2408
|
return "__goscript_get_" + safeIdentifier(name)
|
|
2069
2409
|
}
|
|
2070
2410
|
|
|
2411
|
+
func packageVarInitName(name string) string {
|
|
2412
|
+
return "__goscript_init_" + safeIdentifier(name)
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2071
2415
|
func (o *LoweringOwner) lowerElse(ctx lowerFileContext, stmt ast.Stmt) ([]loweredStmt, []Diagnostic) {
|
|
2072
2416
|
switch typed := stmt.(type) {
|
|
2073
2417
|
case *ast.BlockStmt:
|
|
@@ -2190,6 +2534,19 @@ func (o *LoweringOwner) lowerStmtListAfter(
|
|
|
2190
2534
|
continue
|
|
2191
2535
|
}
|
|
2192
2536
|
}
|
|
2537
|
+
if stmtCtx, nextCtx, ok := o.lowerDeclStatementContext(ctx, stmt); ok {
|
|
2538
|
+
stmtLowered, stmtDiagnostics := o.lowerStmt(stmtCtx, stmt)
|
|
2539
|
+
diagnostics = append(diagnostics, stmtDiagnostics...)
|
|
2540
|
+
if len(stmtLowered) != 0 && len(leading) != 0 {
|
|
2541
|
+
stmtLowered[0].leading = append(leading, stmtLowered[0].leading...)
|
|
2542
|
+
}
|
|
2543
|
+
lowered = append(lowered, stmtLowered...)
|
|
2544
|
+
ctx = nextCtx
|
|
2545
|
+
if endLine := sourceLine(ctx, stmt.End()); endLine != 0 {
|
|
2546
|
+
prevEndLine = endLine
|
|
2547
|
+
}
|
|
2548
|
+
continue
|
|
2549
|
+
}
|
|
2193
2550
|
if stmtCtx, nextCtx, prelude, ok := o.lowerShortDeclStatementContext(ctx, stmt); ok {
|
|
2194
2551
|
stmtLowered, stmtDiagnostics := o.lowerStmt(stmtCtx, stmt)
|
|
2195
2552
|
diagnostics = append(diagnostics, stmtDiagnostics...)
|
|
@@ -2221,23 +2578,61 @@ func (o *LoweringOwner) lowerStmtListAfter(
|
|
|
2221
2578
|
return lowered, diagnostics
|
|
2222
2579
|
}
|
|
2223
2580
|
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2581
|
+
func (o *LoweringOwner) lowerDeclStatementContext(
|
|
2582
|
+
ctx lowerFileContext,
|
|
2583
|
+
stmt ast.Stmt,
|
|
2584
|
+
) (lowerFileContext, lowerFileContext, bool) {
|
|
2585
|
+
declStmt, ok := stmt.(*ast.DeclStmt)
|
|
2586
|
+
if !ok {
|
|
2587
|
+
return ctx, ctx, false
|
|
2588
|
+
}
|
|
2589
|
+
genDecl, ok := declStmt.Decl.(*ast.GenDecl)
|
|
2590
|
+
if !ok || genDecl.Tok != token.VAR {
|
|
2591
|
+
return ctx, ctx, false
|
|
2592
|
+
}
|
|
2593
|
+
aliases := make(map[types.Object]string)
|
|
2594
|
+
for _, spec := range genDecl.Specs {
|
|
2595
|
+
valueSpec, ok := spec.(*ast.ValueSpec)
|
|
2596
|
+
if !ok {
|
|
2597
|
+
continue
|
|
2598
|
+
}
|
|
2599
|
+
for _, name := range valueSpec.Names {
|
|
2600
|
+
if name.Name == "_" {
|
|
2601
|
+
continue
|
|
2602
|
+
}
|
|
2603
|
+
def := ctx.semPkg.source.TypesInfo.Defs[name]
|
|
2604
|
+
if def == nil || aliases[def] != "" {
|
|
2605
|
+
continue
|
|
2606
|
+
}
|
|
2607
|
+
if shortDeclDefShadowsOuterName(name.Name, def) {
|
|
2608
|
+
aliases[def] = ctx.tempName("Shadow")
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
if len(aliases) == 0 {
|
|
2613
|
+
return ctx, ctx, false
|
|
2614
|
+
}
|
|
2615
|
+
nextCtx := ctx.withIdentRefAliases(aliases)
|
|
2616
|
+
return nextCtx, nextCtx, true
|
|
2617
|
+
}
|
|
2618
|
+
|
|
2619
|
+
type gotoStateCluster struct {
|
|
2620
|
+
startIdx int
|
|
2621
|
+
firstLabelIdx int
|
|
2622
|
+
endIdx int
|
|
2623
|
+
labels []gotoStateLabel
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
type gotoStateLabel struct {
|
|
2627
|
+
name string
|
|
2628
|
+
idx int
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
func gotoStateClusterAt(stmts []ast.Stmt, idx int) (gotoStateCluster, bool) {
|
|
2632
|
+
labelIndexes := make(map[string]int)
|
|
2633
|
+
for stmtIdx, stmt := range stmts {
|
|
2634
|
+
labeled, ok := stmt.(*ast.LabeledStmt)
|
|
2635
|
+
if !ok {
|
|
2241
2636
|
continue
|
|
2242
2637
|
}
|
|
2243
2638
|
labelIndexes[safeIdentifier(labeled.Label.Name)] = stmtIdx
|
|
@@ -2387,10 +2782,8 @@ func (o *LoweringOwner) lowerShortDeclStatementContext(
|
|
|
2387
2782
|
if len(oldAliases) == 0 && len(newAliases) == 0 {
|
|
2388
2783
|
return ctx, ctx, nil, false
|
|
2389
2784
|
}
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
maps.Copy(stmtAliases, newAliases)
|
|
2393
|
-
return ctx.withIdentAliases(stmtAliases), ctx.withIdentAliases(newAliases), prelude, true
|
|
2785
|
+
stmtCtx := ctx.withIdentAliases(oldAliases).withIdentRefAliases(newAliases)
|
|
2786
|
+
return stmtCtx, ctx.withIdentRefAliases(newAliases), prelude, true
|
|
2394
2787
|
}
|
|
2395
2788
|
|
|
2396
2789
|
func (o *LoweringOwner) lowerBackwardGotoLoop(
|
|
@@ -2605,6 +2998,9 @@ func (o *LoweringOwner) lowerSendStmt(ctx lowerFileContext, stmt *ast.SendStmt)
|
|
|
2605
2998
|
channel, channelDiagnostics := o.lowerExpr(ctx, stmt.Chan)
|
|
2606
2999
|
value, valueDiagnostics := o.lowerExpr(ctx, stmt.Value)
|
|
2607
3000
|
diagnostics := append(channelDiagnostics, valueDiagnostics...)
|
|
3001
|
+
if channelType, _ := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(stmt.Chan)).Underlying().(*types.Chan); channelType != nil {
|
|
3002
|
+
value = o.lowerValueForTarget(ctx, stmt.Value, channelType.Elem(), value)
|
|
3003
|
+
}
|
|
2608
3004
|
return "await " + o.runtimeOwner.QualifiedHelper(RuntimeHelperChanSend) + "(" + channel + ", " + value + ")", diagnostics
|
|
2609
3005
|
}
|
|
2610
3006
|
|
|
@@ -2616,6 +3012,25 @@ func (o *LoweringOwner) lowerGoStmt(ctx lowerFileContext, stmt *ast.GoStmt) (str
|
|
|
2616
3012
|
}
|
|
2617
3013
|
|
|
2618
3014
|
func (o *LoweringOwner) lowerDeferStmt(ctx lowerFileContext, stmt *ast.DeferStmt) (string, []Diagnostic) {
|
|
3015
|
+
if nestedCall, ok := stmt.Call.Fun.(*ast.CallExpr); ok {
|
|
3016
|
+
callee, diagnostics := o.lowerCallExpr(ctx, nestedCall)
|
|
3017
|
+
args, argDiagnostics := o.lowerCallArgs(ctx, stmt.Call, callTargetSignature(ctx, stmt.Call.Fun))
|
|
3018
|
+
diagnostics = append(diagnostics, argDiagnostics...)
|
|
3019
|
+
calleeTemp := ctx.tempName("DeferCallee")
|
|
3020
|
+
call := o.lowerCallableExpr(ctx, stmt.Call.Fun, calleeTemp) + "(" + strings.Join(args, ", ") + ")"
|
|
3021
|
+
call = o.awaitCallIfNeeded(ctx, stmt.Call.Fun, call)
|
|
3022
|
+
async := strings.Contains(callee, "await ") || strings.Contains(call, "await ")
|
|
3023
|
+
if ctx.deferState != nil {
|
|
3024
|
+
ctx.deferState.used = true
|
|
3025
|
+
if async {
|
|
3026
|
+
ctx.deferState.async = true
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
if async {
|
|
3030
|
+
return "const " + calleeTemp + " = " + callee + "\n__defer.defer(async () => { " + call + " })", diagnostics
|
|
3031
|
+
}
|
|
3032
|
+
return "const " + calleeTemp + " = " + callee + "\n__defer.defer(() => { " + call + " })", diagnostics
|
|
3033
|
+
}
|
|
2619
3034
|
call, diagnostics := o.lowerCallExpr(ctx, stmt.Call)
|
|
2620
3035
|
async := strings.Contains(call, "await ")
|
|
2621
3036
|
if ctx.deferState != nil {
|
|
@@ -2682,41 +3097,51 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
2682
3097
|
isShortDecl := stmt.Tok == token.DEFINE && isShortAssignTargetNew(ctx, lhs)
|
|
2683
3098
|
right, rightDiagnostics := o.lowerExpr(ctx, stmt.Rhs[idx])
|
|
2684
3099
|
diagnostics = append(diagnostics, rightDiagnostics...)
|
|
2685
|
-
targetType := ctx
|
|
3100
|
+
targetType := assignmentTargetType(ctx, lhs)
|
|
2686
3101
|
right = o.lowerValueForTarget(ctx, stmt.Rhs[idx], targetType, right)
|
|
2687
|
-
if
|
|
2688
|
-
|
|
3102
|
+
if targetType != nil && genericCallResultUsesTypeParam(ctx, stmt.Rhs[idx]) {
|
|
3103
|
+
right = "(" + right + " as " + o.tsTypeFor(ctx, targetType) + ")"
|
|
3104
|
+
}
|
|
3105
|
+
if setter, ok := o.packageVarSetterForAssignment(ctx, lhs); ok {
|
|
3106
|
+
value, ok := o.packageVarAssignmentValue(ctx, lhs, targetType, right, stmt.Tok)
|
|
3107
|
+
if !ok {
|
|
3108
|
+
value = right
|
|
3109
|
+
}
|
|
3110
|
+
stmts = append(stmts, loweredStmt{text: setter + "(" + value + ")"})
|
|
2689
3111
|
continue
|
|
2690
3112
|
}
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
keyExpr, keyDiagnostics := o.lowerExpr(ctx, index.Index)
|
|
2696
|
-
diagnostics = append(diagnostics, mapDiagnostics...)
|
|
2697
|
-
diagnostics = append(diagnostics, keyDiagnostics...)
|
|
2698
|
-
stmts = append(stmts, loweredStmt{text: o.runtimeOwner.QualifiedHelper(RuntimeHelperMapSet) + "(" + mapExpr + ", " + keyExpr + ", " + right + ")"})
|
|
3113
|
+
if index, ok := lhs.(*ast.IndexExpr); ok && isMapType(ctx.semPkg.source.TypesInfo.TypeOf(index.X)) && stmt.Tok != token.DEFINE {
|
|
3114
|
+
update, updateDiagnostics := o.lowerMapIndexUpdateStmts(ctx, index, stmt.Tok, right, targetType)
|
|
3115
|
+
diagnostics = append(diagnostics, updateDiagnostics...)
|
|
3116
|
+
stmts = append(stmts, update...)
|
|
2699
3117
|
continue
|
|
2700
3118
|
}
|
|
2701
|
-
|
|
3119
|
+
left, leftDiagnostics := o.lowerAssignmentTarget(ctx, lhs, isShortDecl)
|
|
3120
|
+
diagnostics = append(diagnostics, leftDiagnostics...)
|
|
3121
|
+
star, starTarget := unwrapParenExpr(lhs).(*ast.StarExpr)
|
|
3122
|
+
if starTarget && stmt.Tok == token.ASSIGN && isStructValueType(targetType) {
|
|
2702
3123
|
pointer, pointerDiagnostics := o.lowerPointerValueExpr(ctx, star.X)
|
|
2703
3124
|
diagnostics = append(diagnostics, pointerDiagnostics...)
|
|
2704
3125
|
stmts = append(stmts, loweredStmt{text: o.runtimeOwner.QualifiedHelper(RuntimeHelperAssignStruct) + "(" + pointer + ", " + right + ")"})
|
|
2705
3126
|
continue
|
|
2706
3127
|
}
|
|
2707
|
-
if
|
|
3128
|
+
if starTarget && stmt.Tok == token.ASSIGN {
|
|
2708
3129
|
pointer, pointerDiagnostics := o.lowerPointerStorageExpr(ctx, star.X)
|
|
2709
3130
|
diagnostics = append(diagnostics, pointerDiagnostics...)
|
|
2710
3131
|
stmts = append(stmts, loweredStmt{text: pointer + " = " + right})
|
|
2711
3132
|
continue
|
|
2712
3133
|
}
|
|
2713
|
-
if
|
|
3134
|
+
if starTarget && stmt.Tok != token.DEFINE {
|
|
2714
3135
|
pointer, pointerDiagnostics := o.lowerPointerStorageExpr(ctx, star.X)
|
|
2715
3136
|
diagnostics = append(diagnostics, pointerDiagnostics...)
|
|
2716
3137
|
if stmt.Tok == token.AND_NOT_ASSIGN {
|
|
2717
3138
|
stmts = append(stmts, loweredStmt{text: pointer + " = " + pointer + " & ~(" + right + ")"})
|
|
2718
3139
|
continue
|
|
2719
3140
|
}
|
|
3141
|
+
if value, ok := integerQuotientAssignExpr(targetType, pointer, right, stmt.Tok); ok {
|
|
3142
|
+
stmts = append(stmts, loweredStmt{text: value})
|
|
3143
|
+
continue
|
|
3144
|
+
}
|
|
2720
3145
|
stmts = append(stmts, loweredStmt{text: pointer + " " + stmt.Tok.String() + " " + right})
|
|
2721
3146
|
continue
|
|
2722
3147
|
}
|
|
@@ -2735,6 +3160,10 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
2735
3160
|
stmts = append(stmts, loweredStmt{text: left + " = " + o.runtimeOwner.QualifiedHelper(helper) + "(" + left + ", " + right + ")"})
|
|
2736
3161
|
continue
|
|
2737
3162
|
}
|
|
3163
|
+
if value, ok := integerQuotientAssignExpr(targetType, left, right, stmt.Tok); ok {
|
|
3164
|
+
stmts = append(stmts, loweredStmt{text: value})
|
|
3165
|
+
continue
|
|
3166
|
+
}
|
|
2738
3167
|
op := stmt.Tok.String()
|
|
2739
3168
|
if stmt.Tok == token.DEFINE {
|
|
2740
3169
|
op = "="
|
|
@@ -2744,6 +3173,98 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
2744
3173
|
return stmts, diagnostics
|
|
2745
3174
|
}
|
|
2746
3175
|
|
|
3176
|
+
func (o *LoweringOwner) lowerMapIndexUpdateStmts(
|
|
3177
|
+
ctx lowerFileContext,
|
|
3178
|
+
index *ast.IndexExpr,
|
|
3179
|
+
tok token.Token,
|
|
3180
|
+
right string,
|
|
3181
|
+
targetType types.Type,
|
|
3182
|
+
) ([]loweredStmt, []Diagnostic) {
|
|
3183
|
+
mapExpr, mapDiagnostics := o.lowerExpr(ctx, index.X)
|
|
3184
|
+
keyExpr, keyDiagnostics := o.lowerExpr(ctx, index.Index)
|
|
3185
|
+
diagnostics := append(mapDiagnostics, keyDiagnostics...)
|
|
3186
|
+
if tok == token.ASSIGN {
|
|
3187
|
+
return []loweredStmt{{text: o.runtimeOwner.QualifiedHelper(RuntimeHelperMapSet) + "(" + mapExpr + ", " + keyExpr + ", " + right + ")"}}, diagnostics
|
|
3188
|
+
}
|
|
3189
|
+
mapTemp := ctx.tempName("Map")
|
|
3190
|
+
keyTemp := ctx.tempName("MapKey")
|
|
3191
|
+
current := o.lowerMapGetValue(ctx, index, mapTemp, keyTemp)
|
|
3192
|
+
value := lowerCompoundAssignValue(o.runtimeOwner, targetType, current, right, tok)
|
|
3193
|
+
return []loweredStmt{
|
|
3194
|
+
{text: "const " + mapTemp + " = " + mapExpr},
|
|
3195
|
+
{text: "const " + keyTemp + " = " + keyExpr},
|
|
3196
|
+
{text: o.runtimeOwner.QualifiedHelper(RuntimeHelperMapSet) + "(" + mapTemp + ", " + keyTemp + ", " + value + ")"},
|
|
3197
|
+
}, diagnostics
|
|
3198
|
+
}
|
|
3199
|
+
|
|
3200
|
+
func lowerCompoundAssignValue(
|
|
3201
|
+
runtimeOwner *RuntimeContractOwner,
|
|
3202
|
+
targetType types.Type,
|
|
3203
|
+
left string,
|
|
3204
|
+
right string,
|
|
3205
|
+
tok token.Token,
|
|
3206
|
+
) string {
|
|
3207
|
+
if helper, ok := wideIntegerAssignHelper(targetType, tok); ok {
|
|
3208
|
+
return runtimeOwner.QualifiedHelper(helper) + "(" + left + ", " + right + ")"
|
|
3209
|
+
}
|
|
3210
|
+
if value, ok := integerQuotientAssignValueExpr(targetType, left, right, tok); ok {
|
|
3211
|
+
return value
|
|
3212
|
+
}
|
|
3213
|
+
switch tok {
|
|
3214
|
+
case token.ADD_ASSIGN:
|
|
3215
|
+
return left + " + " + right
|
|
3216
|
+
case token.SUB_ASSIGN:
|
|
3217
|
+
return left + " - " + right
|
|
3218
|
+
case token.MUL_ASSIGN:
|
|
3219
|
+
return left + " * " + right
|
|
3220
|
+
case token.QUO_ASSIGN:
|
|
3221
|
+
return left + " / " + right
|
|
3222
|
+
case token.REM_ASSIGN:
|
|
3223
|
+
return left + " % " + right
|
|
3224
|
+
case token.AND_ASSIGN:
|
|
3225
|
+
return left + " & " + right
|
|
3226
|
+
case token.OR_ASSIGN:
|
|
3227
|
+
return left + " | " + right
|
|
3228
|
+
case token.XOR_ASSIGN:
|
|
3229
|
+
return left + " ^ " + right
|
|
3230
|
+
case token.SHL_ASSIGN:
|
|
3231
|
+
return left + " << " + right
|
|
3232
|
+
case token.SHR_ASSIGN:
|
|
3233
|
+
return left + " >> " + right
|
|
3234
|
+
case token.AND_NOT_ASSIGN:
|
|
3235
|
+
return left + " & ~(" + right + ")"
|
|
3236
|
+
default:
|
|
3237
|
+
return right
|
|
3238
|
+
}
|
|
3239
|
+
}
|
|
3240
|
+
|
|
3241
|
+
func integerQuotientAssignExpr(targetType types.Type, left string, right string, tok token.Token) (string, bool) {
|
|
3242
|
+
value, ok := integerQuotientAssignValueExpr(targetType, left, right, tok)
|
|
3243
|
+
if !ok {
|
|
3244
|
+
return "", false
|
|
3245
|
+
}
|
|
3246
|
+
return left + " = " + value, true
|
|
3247
|
+
}
|
|
3248
|
+
|
|
3249
|
+
func assignmentTargetType(ctx lowerFileContext, lhs ast.Expr) types.Type {
|
|
3250
|
+
if ident, ok := lhs.(*ast.Ident); ok {
|
|
3251
|
+
if obj := ctx.semPkg.source.TypesInfo.Defs[ident]; obj != nil {
|
|
3252
|
+
return obj.Type()
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
return ctx.semPkg.source.TypesInfo.TypeOf(lhs)
|
|
3256
|
+
}
|
|
3257
|
+
|
|
3258
|
+
func integerQuotientAssignValueExpr(targetType types.Type, left string, right string, tok token.Token) (string, bool) {
|
|
3259
|
+
if tok != token.QUO_ASSIGN || !isIntegerType(targetType) {
|
|
3260
|
+
return "", false
|
|
3261
|
+
}
|
|
3262
|
+
if bits, ok := unsignedIntegerBits(targetType); ok && bits <= 32 {
|
|
3263
|
+
return "(" + left + " / " + right + ") >>> 0", true
|
|
3264
|
+
}
|
|
3265
|
+
return "Math.trunc(" + left + " / " + right + ")", true
|
|
3266
|
+
}
|
|
3267
|
+
|
|
2747
3268
|
func wideIntegerAssignHelper(targetType types.Type, tok token.Token) (RuntimeHelper, bool) {
|
|
2748
3269
|
if !isFixedWideIntegerType(targetType) {
|
|
2749
3270
|
return "", false
|
|
@@ -2754,17 +3275,21 @@ func wideIntegerAssignHelper(targetType types.Type, tok token.Token) (RuntimeHel
|
|
|
2754
3275
|
case token.SHR_ASSIGN:
|
|
2755
3276
|
return RuntimeHelperUint64Shr, true
|
|
2756
3277
|
case token.MUL_ASSIGN:
|
|
2757
|
-
return RuntimeHelperUint64Mul, true
|
|
3278
|
+
return wideIntegerHelper(isFixedSignedWideIntegerType(targetType), RuntimeHelperUint64Mul, RuntimeHelperInt64Mul), true
|
|
3279
|
+
case token.QUO_ASSIGN:
|
|
3280
|
+
return wideIntegerHelper(isFixedSignedWideIntegerType(targetType), RuntimeHelperUint64Div, RuntimeHelperInt64Div), true
|
|
3281
|
+
case token.REM_ASSIGN:
|
|
3282
|
+
return wideIntegerHelper(isFixedSignedWideIntegerType(targetType), RuntimeHelperUint64Mod, RuntimeHelperInt64Mod), true
|
|
2758
3283
|
case token.ADD_ASSIGN:
|
|
2759
|
-
return RuntimeHelperUint64Add, true
|
|
3284
|
+
return wideIntegerHelper(isFixedSignedWideIntegerType(targetType), RuntimeHelperUint64Add, RuntimeHelperInt64Add), true
|
|
2760
3285
|
case token.SUB_ASSIGN:
|
|
2761
|
-
return RuntimeHelperUint64Sub, true
|
|
3286
|
+
return wideIntegerHelper(isFixedSignedWideIntegerType(targetType), RuntimeHelperUint64Sub, RuntimeHelperInt64Sub), true
|
|
2762
3287
|
case token.AND_ASSIGN:
|
|
2763
|
-
return RuntimeHelperUint64And, true
|
|
3288
|
+
return wideIntegerHelper(isFixedSignedWideIntegerType(targetType), RuntimeHelperUint64And, RuntimeHelperInt64And), true
|
|
2764
3289
|
case token.OR_ASSIGN:
|
|
2765
|
-
return RuntimeHelperUint64Or, true
|
|
3290
|
+
return wideIntegerHelper(isFixedSignedWideIntegerType(targetType), RuntimeHelperUint64Or, RuntimeHelperInt64Or), true
|
|
2766
3291
|
case token.XOR_ASSIGN:
|
|
2767
|
-
return RuntimeHelperUint64Xor, true
|
|
3292
|
+
return wideIntegerHelper(isFixedSignedWideIntegerType(targetType), RuntimeHelperUint64Xor, RuntimeHelperInt64Xor), true
|
|
2768
3293
|
default:
|
|
2769
3294
|
return "", false
|
|
2770
3295
|
}
|
|
@@ -2834,14 +3359,12 @@ func (o *LoweringOwner) shortDeclTypeAnnotation(ctx lowerFileContext, lhs ast.Ex
|
|
|
2834
3359
|
if obj == nil {
|
|
2835
3360
|
return ""
|
|
2836
3361
|
}
|
|
2837
|
-
if signature := unnamedSignatureForType(obj.Type()); signature != nil && rhsIsMethodValue(ctx, rhs) {
|
|
2838
|
-
return ": " + o.tsAsyncCompatibleFunctionTypeFor(ctx, signature)
|
|
2839
|
-
}
|
|
2840
3362
|
if signature := unnamedSignatureForType(obj.Type()); signature != nil {
|
|
2841
|
-
|
|
2842
|
-
if
|
|
2843
|
-
|
|
3363
|
+
typ := o.tsAsyncCompatibleFunctionTypeFor(ctx, signature)
|
|
3364
|
+
if ctx.model.needsVarRef[obj] {
|
|
3365
|
+
typ = "$.VarRef<" + typ + ">"
|
|
2844
3366
|
}
|
|
3367
|
+
return ": " + typ
|
|
2845
3368
|
}
|
|
2846
3369
|
if !shortDeclNeedsTypeAnnotation(obj.Type()) {
|
|
2847
3370
|
return ""
|
|
@@ -2852,9 +3375,11 @@ func (o *LoweringOwner) shortDeclTypeAnnotation(ctx lowerFileContext, lhs ast.Ex
|
|
|
2852
3375
|
func shortDeclNeedsTypeAnnotation(typ types.Type) bool {
|
|
2853
3376
|
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
2854
3377
|
case *types.Pointer:
|
|
2855
|
-
return namedStructType(typed.Elem()) != nil
|
|
3378
|
+
return namedStructType(typed.Elem()) != nil || namedNonStructType(typed.Elem()) != nil
|
|
2856
3379
|
case *types.Map:
|
|
2857
3380
|
return true
|
|
3381
|
+
case *types.Slice:
|
|
3382
|
+
return true
|
|
2858
3383
|
default:
|
|
2859
3384
|
return false
|
|
2860
3385
|
}
|
|
@@ -2895,7 +3420,7 @@ func (o *LoweringOwner) lowerStarTargetAssignmentStmt(
|
|
|
2895
3420
|
lhs ast.Expr,
|
|
2896
3421
|
right string,
|
|
2897
3422
|
) (loweredStmt, []Diagnostic, bool) {
|
|
2898
|
-
star, ok := lhs.(*ast.StarExpr)
|
|
3423
|
+
star, ok := unwrapParenExpr(lhs).(*ast.StarExpr)
|
|
2899
3424
|
if !ok {
|
|
2900
3425
|
return loweredStmt{}, nil, false
|
|
2901
3426
|
}
|
|
@@ -2915,7 +3440,7 @@ func (o *LoweringOwner) lowerTupleReassignmentStmt(
|
|
|
2915
3440
|
diagnostics []Diagnostic,
|
|
2916
3441
|
) ([]loweredStmt, []Diagnostic) {
|
|
2917
3442
|
tempName := ctx.tempName("Tuple")
|
|
2918
|
-
stmts := []loweredStmt{{text: "let " + tempName + " = " + right}}
|
|
3443
|
+
stmts := []loweredStmt{{text: "let " + tempName + ": any = " + right}}
|
|
2919
3444
|
for idx, lhs := range stmt.Lhs {
|
|
2920
3445
|
if ident, ok := lhs.(*ast.Ident); ok && ident.Name == "_" {
|
|
2921
3446
|
continue
|
|
@@ -3064,8 +3589,8 @@ func shortDeclDefShadowsOuterName(name string, def types.Object) bool {
|
|
|
3064
3589
|
if scope == def.Parent() {
|
|
3065
3590
|
continue
|
|
3066
3591
|
}
|
|
3067
|
-
obj
|
|
3068
|
-
if
|
|
3592
|
+
obj := scope.Lookup(name)
|
|
3593
|
+
if obj != nil && obj.Pos().IsValid() && obj.Pos() < def.Pos() {
|
|
3069
3594
|
return true
|
|
3070
3595
|
}
|
|
3071
3596
|
}
|
|
@@ -3281,6 +3806,9 @@ func (o *LoweringOwner) lowerReturnStmt(ctx lowerFileContext, stmt *ast.ReturnSt
|
|
|
3281
3806
|
if ctx.rangeBranch != nil {
|
|
3282
3807
|
return o.lowerRangeFuncReturnStmt(ctx, stmt)
|
|
3283
3808
|
}
|
|
3809
|
+
if o.returnNeedsNamedResultDefer(ctx) {
|
|
3810
|
+
return o.lowerNamedResultDeferReturnStmt(ctx, stmt)
|
|
3811
|
+
}
|
|
3284
3812
|
if len(stmt.Results) == 0 {
|
|
3285
3813
|
if result, ok := o.lowerNamedResultReturn(ctx); ok {
|
|
3286
3814
|
return "return " + result, nil
|
|
@@ -3313,6 +3841,125 @@ func (o *LoweringOwner) lowerReturnStmt(ctx lowerFileContext, stmt *ast.ReturnSt
|
|
|
3313
3841
|
return "return [" + strings.Join(parts, ", ") + "]", diagnostics
|
|
3314
3842
|
}
|
|
3315
3843
|
|
|
3844
|
+
func (o *LoweringOwner) returnNeedsNamedResultDefer(ctx lowerFileContext) bool {
|
|
3845
|
+
if ctx.deferState == nil || !ctx.deferState.used || ctx.signature == nil || ctx.signature.Results() == nil {
|
|
3846
|
+
return false
|
|
3847
|
+
}
|
|
3848
|
+
for result := range ctx.signature.Results().Variables() {
|
|
3849
|
+
if result.Name() != "" {
|
|
3850
|
+
return true
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3853
|
+
return false
|
|
3854
|
+
}
|
|
3855
|
+
|
|
3856
|
+
func (o *LoweringOwner) lowerNamedResultDeferReturnStmt(ctx lowerFileContext, stmt *ast.ReturnStmt) (string, []Diagnostic) {
|
|
3857
|
+
var diagnostics []Diagnostic
|
|
3858
|
+
var lines []string
|
|
3859
|
+
explicitTemp := ""
|
|
3860
|
+
if len(stmt.Results) != 0 {
|
|
3861
|
+
var value string
|
|
3862
|
+
var values []string
|
|
3863
|
+
if len(stmt.Results) == 1 && ctx.signature.Results().Len() > 1 {
|
|
3864
|
+
expr, exprDiagnostics := o.lowerExpr(ctx, stmt.Results[0])
|
|
3865
|
+
diagnostics = append(diagnostics, exprDiagnostics...)
|
|
3866
|
+
if prefix, tuple, ok := o.lowerTupleReturnValue(ctx, stmt.Results[0], expr); ok {
|
|
3867
|
+
lines = append(lines, prefix)
|
|
3868
|
+
value = tuple
|
|
3869
|
+
} else {
|
|
3870
|
+
value = expr
|
|
3871
|
+
}
|
|
3872
|
+
} else {
|
|
3873
|
+
values = make([]string, 0, len(stmt.Results))
|
|
3874
|
+
for idx, result := range stmt.Results {
|
|
3875
|
+
expr, exprDiagnostics := o.lowerExpr(ctx, result)
|
|
3876
|
+
diagnostics = append(diagnostics, exprDiagnostics...)
|
|
3877
|
+
if idx < ctx.signature.Results().Len() {
|
|
3878
|
+
expr = o.lowerValueForTarget(ctx, result, ctx.signature.Results().At(idx).Type(), expr)
|
|
3879
|
+
}
|
|
3880
|
+
values = append(values, expr)
|
|
3881
|
+
}
|
|
3882
|
+
}
|
|
3883
|
+
temp := ctx.tempName("Return")
|
|
3884
|
+
explicitTemp = temp
|
|
3885
|
+
tempType := o.tsSignatureResultFor(ctx, ctx.signature)
|
|
3886
|
+
if value != "" {
|
|
3887
|
+
lines = append(lines, "const "+temp+": "+tempType+" = "+value)
|
|
3888
|
+
} else if len(values) == 1 {
|
|
3889
|
+
lines = append(lines, "const "+temp+": "+tempType+" = "+values[0])
|
|
3890
|
+
} else {
|
|
3891
|
+
lines = append(lines, "const "+temp+": "+tempType+" = ["+strings.Join(values, ", ")+"]")
|
|
3892
|
+
}
|
|
3893
|
+
for idx := range ctx.signature.Results().Len() {
|
|
3894
|
+
result := ctx.signature.Results().At(idx)
|
|
3895
|
+
name := result.Name()
|
|
3896
|
+
if name == "" || name == "_" {
|
|
3897
|
+
continue
|
|
3898
|
+
}
|
|
3899
|
+
target := safeIdentifier(name)
|
|
3900
|
+
if ctx.model.needsVarRef[result] {
|
|
3901
|
+
target += ".value"
|
|
3902
|
+
}
|
|
3903
|
+
source := temp
|
|
3904
|
+
if ctx.signature.Results().Len() > 1 {
|
|
3905
|
+
source += "[" + strconv.Itoa(idx) + "]"
|
|
3906
|
+
}
|
|
3907
|
+
lines = append(lines, target+" = "+source)
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
lines = append(lines, o.lowerDeferDisposeStmt(ctx))
|
|
3911
|
+
if result, ok := o.lowerNamedResultReturnWithExplicitTemp(ctx, explicitTemp); ok {
|
|
3912
|
+
lines = append(lines, "return "+result)
|
|
3913
|
+
} else {
|
|
3914
|
+
lines = append(lines, "return")
|
|
3915
|
+
}
|
|
3916
|
+
return strings.Join(lines, "\n"), diagnostics
|
|
3917
|
+
}
|
|
3918
|
+
|
|
3919
|
+
func (o *LoweringOwner) lowerNamedResultReturnWithExplicitTemp(ctx lowerFileContext, explicitTemp string) (string, bool) {
|
|
3920
|
+
if explicitTemp == "" {
|
|
3921
|
+
return o.lowerNamedResultReturn(ctx)
|
|
3922
|
+
}
|
|
3923
|
+
parts := make([]string, 0, ctx.signature.Results().Len())
|
|
3924
|
+
hasNamedResult := false
|
|
3925
|
+
multi := ctx.signature.Results().Len() > 1
|
|
3926
|
+
for idx := range ctx.signature.Results().Len() {
|
|
3927
|
+
result := ctx.signature.Results().At(idx)
|
|
3928
|
+
name := result.Name()
|
|
3929
|
+
if name == "" || name == "_" {
|
|
3930
|
+
source := explicitTemp
|
|
3931
|
+
if multi {
|
|
3932
|
+
source += "[" + strconv.Itoa(idx) + "]"
|
|
3933
|
+
}
|
|
3934
|
+
parts = append(parts, source)
|
|
3935
|
+
if name != "" {
|
|
3936
|
+
hasNamedResult = true
|
|
3937
|
+
}
|
|
3938
|
+
continue
|
|
3939
|
+
}
|
|
3940
|
+
hasNamedResult = true
|
|
3941
|
+
returnExpr := safeIdentifier(name)
|
|
3942
|
+
if ctx.model.needsVarRef[result] {
|
|
3943
|
+
returnExpr += ".value"
|
|
3944
|
+
}
|
|
3945
|
+
parts = append(parts, returnExpr)
|
|
3946
|
+
}
|
|
3947
|
+
if !hasNamedResult {
|
|
3948
|
+
return "", false
|
|
3949
|
+
}
|
|
3950
|
+
if len(parts) == 1 {
|
|
3951
|
+
return parts[0], true
|
|
3952
|
+
}
|
|
3953
|
+
return "[" + strings.Join(parts, ", ") + "]", true
|
|
3954
|
+
}
|
|
3955
|
+
|
|
3956
|
+
func (o *LoweringOwner) lowerDeferDisposeStmt(ctx lowerFileContext) string {
|
|
3957
|
+
if ctx.deferState != nil && ctx.deferState.async {
|
|
3958
|
+
return "await __defer[Symbol.asyncDispose]()"
|
|
3959
|
+
}
|
|
3960
|
+
return "__defer[Symbol.dispose]()"
|
|
3961
|
+
}
|
|
3962
|
+
|
|
3316
3963
|
func (o *LoweringOwner) lowerBodylessReturnStmt(ctx lowerFileContext, signature *types.Signature) (string, bool) {
|
|
3317
3964
|
if signature.Results().Len() == 0 {
|
|
3318
3965
|
return "", false
|
|
@@ -3434,6 +4081,9 @@ func genericCallResultUsesTypeParam(ctx lowerFileContext, expr ast.Expr) bool {
|
|
|
3434
4081
|
return false
|
|
3435
4082
|
}
|
|
3436
4083
|
signature := genericFunctionSignatureForCall(ctx, call.Fun)
|
|
4084
|
+
if signature == nil {
|
|
4085
|
+
signature = sourceFunctionSignatureForCall(ctx, call.Fun)
|
|
4086
|
+
}
|
|
3437
4087
|
if signature == nil || signature.Results() == nil || signature.Results().Len() != 1 {
|
|
3438
4088
|
return false
|
|
3439
4089
|
}
|
|
@@ -3446,6 +4096,9 @@ func genericCallTupleResultTypeParamIndexes(ctx lowerFileContext, expr ast.Expr)
|
|
|
3446
4096
|
return nil
|
|
3447
4097
|
}
|
|
3448
4098
|
signature := genericFunctionSignatureForCall(ctx, call.Fun)
|
|
4099
|
+
if signature == nil {
|
|
4100
|
+
signature = sourceFunctionSignatureForCall(ctx, call.Fun)
|
|
4101
|
+
}
|
|
3449
4102
|
if signature == nil || signature.Results() == nil || signature.Results().Len() < 2 {
|
|
3450
4103
|
return nil
|
|
3451
4104
|
}
|
|
@@ -3471,6 +4124,30 @@ func genericFunctionSignatureForCall(ctx lowerFileContext, fun ast.Expr) *types.
|
|
|
3471
4124
|
}
|
|
3472
4125
|
}
|
|
3473
4126
|
|
|
4127
|
+
func sourceFunctionSignatureForCall(ctx lowerFileContext, fun ast.Expr) *types.Signature {
|
|
4128
|
+
for {
|
|
4129
|
+
switch typed := ast.Unparen(fun).(type) {
|
|
4130
|
+
case *ast.IndexExpr:
|
|
4131
|
+
fun = typed.X
|
|
4132
|
+
case *ast.IndexListExpr:
|
|
4133
|
+
fun = typed.X
|
|
4134
|
+
default:
|
|
4135
|
+
if ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
4136
|
+
return nil
|
|
4137
|
+
}
|
|
4138
|
+
fn := calledFunction(ctx.semPkg.source, fun)
|
|
4139
|
+
if fn == nil {
|
|
4140
|
+
return nil
|
|
4141
|
+
}
|
|
4142
|
+
if origin := fn.Origin(); origin != nil {
|
|
4143
|
+
fn = origin
|
|
4144
|
+
}
|
|
4145
|
+
signature, _ := fn.Type().(*types.Signature)
|
|
4146
|
+
return signature
|
|
4147
|
+
}
|
|
4148
|
+
}
|
|
4149
|
+
}
|
|
4150
|
+
|
|
3474
4151
|
func typeContainsTypeParam(typ types.Type) bool {
|
|
3475
4152
|
return typeContainsTypeParamSeen(typ, make(map[types.Type]bool))
|
|
3476
4153
|
}
|
|
@@ -3569,27 +4246,57 @@ func (o *LoweringOwner) lowerNamedResults(ctx lowerFileContext, signature *types
|
|
|
3569
4246
|
}
|
|
3570
4247
|
|
|
3571
4248
|
func (o *LoweringOwner) lowerNamedResultReturn(ctx lowerFileContext) (string, bool) {
|
|
3572
|
-
|
|
3573
|
-
if len(results) == 0 {
|
|
4249
|
+
if ctx.signature == nil || ctx.signature.Results() == nil || ctx.signature.Results().Len() == 0 {
|
|
3574
4250
|
return "", false
|
|
3575
4251
|
}
|
|
3576
|
-
|
|
3577
|
-
|
|
4252
|
+
parts := make([]string, 0, ctx.signature.Results().Len())
|
|
4253
|
+
hasNamedResult := false
|
|
4254
|
+
for result := range ctx.signature.Results().Variables() {
|
|
4255
|
+
name := result.Name()
|
|
4256
|
+
if name == "" {
|
|
4257
|
+
parts = append(parts, o.lowerDeclarationZeroValueExpr(ctx, result.Type()))
|
|
4258
|
+
continue
|
|
4259
|
+
}
|
|
4260
|
+
hasNamedResult = true
|
|
4261
|
+
if name == "_" {
|
|
4262
|
+
parts = append(parts, o.lowerDeclarationZeroValueExpr(ctx, result.Type()))
|
|
4263
|
+
continue
|
|
4264
|
+
}
|
|
4265
|
+
returnExpr := safeIdentifier(name)
|
|
4266
|
+
if ctx.model.needsVarRef[result] {
|
|
4267
|
+
returnExpr += ".value"
|
|
4268
|
+
}
|
|
4269
|
+
parts = append(parts, returnExpr)
|
|
4270
|
+
}
|
|
4271
|
+
if !hasNamedResult {
|
|
4272
|
+
return "", false
|
|
3578
4273
|
}
|
|
3579
|
-
parts
|
|
3580
|
-
|
|
3581
|
-
parts = append(parts, result.returnExpr)
|
|
4274
|
+
if len(parts) == 1 {
|
|
4275
|
+
return parts[0], true
|
|
3582
4276
|
}
|
|
3583
4277
|
return "[" + strings.Join(parts, ", ") + "]", true
|
|
3584
4278
|
}
|
|
3585
4279
|
|
|
3586
4280
|
func (o *LoweringOwner) lowerForStmt(ctx lowerFileContext, stmt *ast.ForStmt) (loweredStmt, []Diagnostic) {
|
|
3587
|
-
bodyCtx := ctx.withoutRangeLoopBranches()
|
|
4281
|
+
bodyCtx := ctx.withoutRangeLoopBranches().withoutLoopLabel()
|
|
3588
4282
|
loopLabel := ""
|
|
3589
4283
|
if stmtListNeedsLoopBranchLabel(stmt.Body.List) {
|
|
3590
4284
|
loopLabel = ctx.tempName("Loop")
|
|
3591
4285
|
bodyCtx = bodyCtx.withLoopLabel(loopLabel)
|
|
3592
4286
|
}
|
|
4287
|
+
initCtx := ctx
|
|
4288
|
+
loopCtx := ctx
|
|
4289
|
+
var initPrelude []loweredStmt
|
|
4290
|
+
if assign, ok := stmt.Init.(*ast.AssignStmt); ok && assign.Tok == token.DEFINE {
|
|
4291
|
+
oldAliases, prelude := o.lowerShortDeclShadowAliases(ctx, assign)
|
|
4292
|
+
newAliases := o.lowerShortDeclNewShadowAliases(ctx, assign)
|
|
4293
|
+
if len(oldAliases) != 0 || len(newAliases) != 0 {
|
|
4294
|
+
initCtx = ctx.withIdentAliases(oldAliases).withIdentRefAliases(newAliases)
|
|
4295
|
+
loopCtx = ctx.withIdentRefAliases(newAliases)
|
|
4296
|
+
bodyCtx = bodyCtx.withIdentRefAliases(newAliases)
|
|
4297
|
+
initPrelude = prelude
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
3593
4300
|
if stmt.Init == nil && stmt.Post == nil {
|
|
3594
4301
|
cond := "true"
|
|
3595
4302
|
var diagnostics []Diagnostic
|
|
@@ -3614,19 +4321,19 @@ func (o *LoweringOwner) lowerForStmt(ctx lowerFileContext, stmt *ast.ForStmt) (l
|
|
|
3614
4321
|
init := ""
|
|
3615
4322
|
var diagnostics []Diagnostic
|
|
3616
4323
|
if stmt.Init != nil {
|
|
3617
|
-
lowered, initDiagnostics := o.lowerForInitStmt(
|
|
4324
|
+
lowered, initDiagnostics := o.lowerForInitStmt(initCtx, stmt.Init)
|
|
3618
4325
|
diagnostics = append(diagnostics, initDiagnostics...)
|
|
3619
4326
|
init = lowered
|
|
3620
4327
|
}
|
|
3621
4328
|
cond := ""
|
|
3622
4329
|
if stmt.Cond != nil {
|
|
3623
4330
|
var condDiagnostics []Diagnostic
|
|
3624
|
-
cond, condDiagnostics = o.lowerExpr(
|
|
4331
|
+
cond, condDiagnostics = o.lowerExpr(loopCtx, stmt.Cond)
|
|
3625
4332
|
diagnostics = append(diagnostics, condDiagnostics...)
|
|
3626
4333
|
}
|
|
3627
4334
|
post := ""
|
|
3628
4335
|
if stmt.Post != nil {
|
|
3629
|
-
lowered, postDiagnostics := o.lowerForPostStmt(
|
|
4336
|
+
lowered, postDiagnostics := o.lowerForPostStmt(loopCtx, stmt.Post)
|
|
3630
4337
|
diagnostics = append(diagnostics, postDiagnostics...)
|
|
3631
4338
|
post = lowered
|
|
3632
4339
|
}
|
|
@@ -3636,11 +4343,15 @@ func (o *LoweringOwner) lowerForStmt(ctx lowerFileContext, stmt *ast.ForStmt) (l
|
|
|
3636
4343
|
if loopLabel != "" {
|
|
3637
4344
|
text = loopLabel + ": " + text
|
|
3638
4345
|
}
|
|
3639
|
-
|
|
4346
|
+
forStmt := loweredStmt{
|
|
3640
4347
|
hasBlock: true,
|
|
3641
4348
|
text: text,
|
|
3642
4349
|
children: body,
|
|
3643
|
-
}
|
|
4350
|
+
}
|
|
4351
|
+
if len(initPrelude) != 0 {
|
|
4352
|
+
return loweredStmt{children: append(initPrelude, forStmt)}, diagnostics
|
|
4353
|
+
}
|
|
4354
|
+
return forStmt, diagnostics
|
|
3644
4355
|
}
|
|
3645
4356
|
|
|
3646
4357
|
func (o *LoweringOwner) lowerForInitStmt(ctx lowerFileContext, stmt ast.Stmt) (string, []Diagnostic) {
|
|
@@ -3729,9 +4440,13 @@ func (o *LoweringOwner) lowerForPostStmt(ctx lowerFileContext, stmt ast.Stmt) (s
|
|
|
3729
4440
|
diagnostics = append(diagnostics, leftDiagnostics...)
|
|
3730
4441
|
lefts = append(lefts, left)
|
|
3731
4442
|
}
|
|
3732
|
-
for
|
|
4443
|
+
for idx, rhs := range assign.Rhs {
|
|
3733
4444
|
right, rightDiagnostics := o.lowerExpr(ctx, rhs)
|
|
3734
4445
|
diagnostics = append(diagnostics, rightDiagnostics...)
|
|
4446
|
+
if idx < len(assign.Lhs) {
|
|
4447
|
+
targetType := ctx.semPkg.source.TypesInfo.TypeOf(assign.Lhs[idx])
|
|
4448
|
+
right = o.lowerValueForTarget(ctx, rhs, targetType, right)
|
|
4449
|
+
}
|
|
3735
4450
|
rights = append(rights, right)
|
|
3736
4451
|
}
|
|
3737
4452
|
return "[" + strings.Join(lefts, ", ") + "] = [" + strings.Join(rights, ", ") + "]", diagnostics
|
|
@@ -3746,7 +4461,7 @@ func (o *LoweringOwner) lowerForPostStmt(ctx lowerFileContext, stmt ast.Stmt) (s
|
|
|
3746
4461
|
func (o *LoweringOwner) lowerRangeStmt(ctx lowerFileContext, stmt *ast.RangeStmt) (loweredStmt, []Diagnostic) {
|
|
3747
4462
|
rangeValue, diagnostics := o.lowerExpr(ctx, stmt.X)
|
|
3748
4463
|
aliases := o.lowerRangeDeclShadowAliases(ctx, stmt)
|
|
3749
|
-
bodyCtx := ctx
|
|
4464
|
+
bodyCtx := ctx.withoutLoopLabel()
|
|
3750
4465
|
if len(aliases) != 0 {
|
|
3751
4466
|
bodyCtx = bodyCtx.withIdentAliases(aliases)
|
|
3752
4467
|
}
|
|
@@ -3795,23 +4510,21 @@ func (o *LoweringOwner) lowerRangeStmt(ctx lowerFileContext, stmt *ast.RangeStmt
|
|
|
3795
4510
|
if strings.HasPrefix(rangeTarget, "await ") {
|
|
3796
4511
|
rangeTarget = "(" + rangeTarget + ")"
|
|
3797
4512
|
}
|
|
3798
|
-
key := keyName
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
value := valueName
|
|
3803
|
-
if value == "" {
|
|
3804
|
-
value = "__rangeValue"
|
|
3805
|
-
}
|
|
4513
|
+
key, keyBindings, keyDiagnostics := o.lowerMapRangeBinding(ctx, stmt.Key, keyName, "__rangeKey", "RangeKey", stmt.Tok == token.DEFINE)
|
|
4514
|
+
value, valueBindings, valueDiagnostics := o.lowerMapRangeBinding(ctx, stmt.Value, valueName, "__rangeValue", "RangeValue", stmt.Tok == token.DEFINE)
|
|
4515
|
+
diagnostics = append(diagnostics, keyDiagnostics...)
|
|
4516
|
+
diagnostics = append(diagnostics, valueDiagnostics...)
|
|
3806
4517
|
binding := "const"
|
|
3807
4518
|
if rangeBindingAssignedInBody(ctx, stmt.Key, stmt.Body) ||
|
|
3808
4519
|
rangeBindingAssignedInBody(ctx, stmt.Value, stmt.Body) {
|
|
3809
4520
|
binding = "let"
|
|
3810
4521
|
}
|
|
4522
|
+
children := append(keyBindings, valueBindings...)
|
|
4523
|
+
children = append(children, body...)
|
|
3811
4524
|
return loweredStmt{
|
|
3812
4525
|
hasBlock: true,
|
|
3813
4526
|
text: "for (" + binding + " [" + key + ", " + value + "] of " + rangeTarget + "?.entries() ?? [])",
|
|
3814
|
-
children:
|
|
4527
|
+
children: children,
|
|
3815
4528
|
}, diagnostics
|
|
3816
4529
|
}
|
|
3817
4530
|
if isStringType(rangeType) {
|
|
@@ -3848,8 +4561,12 @@ func (o *LoweringOwner) lowerRangeStmt(ctx lowerFileContext, stmt *ast.RangeStmt
|
|
|
3848
4561
|
|
|
3849
4562
|
body, bodyDiagnostics := o.lowerBlock(bodyCtx.withoutRangeLoopBranches(), stmt.Body)
|
|
3850
4563
|
diagnostics = append(diagnostics, bodyDiagnostics...)
|
|
3851
|
-
rangeTarget :=
|
|
3852
|
-
|
|
4564
|
+
rangeTarget := ctx.tempName("RangeTarget")
|
|
4565
|
+
rangeTargetValue := o.lowerArrayPointerTarget(ctx, rangeValue, rangeType)
|
|
4566
|
+
indexTarget := rangeTarget
|
|
4567
|
+
if isNilableType(rangeType) {
|
|
4568
|
+
indexTarget += "!"
|
|
4569
|
+
}
|
|
3853
4570
|
indexName := keyName
|
|
3854
4571
|
if indexName == "" {
|
|
3855
4572
|
indexName = "__rangeIndex"
|
|
@@ -3864,7 +4581,7 @@ func (o *LoweringOwner) lowerRangeStmt(ctx lowerFileContext, stmt *ast.RangeStmt
|
|
|
3864
4581
|
}
|
|
3865
4582
|
return loweredStmt{
|
|
3866
4583
|
hasBlock: true,
|
|
3867
|
-
text: "for (let " + indexName + " = 0; " + indexName + " < " + o.runtimeOwner.QualifiedHelper(RuntimeHelperLen) + "(" + rangeTarget + "); " + indexName + "++)",
|
|
4584
|
+
text: "for (let " + rangeTarget + " = " + rangeTargetValue + ", " + indexName + " = 0; " + indexName + " < " + o.runtimeOwner.QualifiedHelper(RuntimeHelperLen) + "(" + rangeTarget + "); " + indexName + "++)",
|
|
3868
4585
|
children: children,
|
|
3869
4586
|
}, diagnostics
|
|
3870
4587
|
}
|
|
@@ -3933,18 +4650,19 @@ func (o *LoweringOwner) lowerRangeFuncStmt(
|
|
|
3933
4650
|
rangeBranch.value = ctx.tempName("RangeReturnValue")
|
|
3934
4651
|
rangeBranch.resultType = o.tsSignatureResultFor(ctx, ctx.signature)
|
|
3935
4652
|
}
|
|
3936
|
-
body, diagnostics := o.lowerBlock(ctx.withRangeBranch(rangeBranch), stmt.Body)
|
|
4653
|
+
body, diagnostics := o.lowerBlock(ctx.withoutLoopLabel().withRangeBranch(rangeBranch), stmt.Body)
|
|
3937
4654
|
if stmt.Tok != token.DEFINE {
|
|
3938
4655
|
assignments, assignmentDiagnostics := o.lowerRangeFuncAssignments(ctx, stmt, paramNames)
|
|
3939
4656
|
diagnostics = append(diagnostics, assignmentDiagnostics...)
|
|
3940
4657
|
body = append(assignments, body...)
|
|
3941
4658
|
}
|
|
4659
|
+
async := ctx.asyncFunction
|
|
3942
4660
|
|
|
3943
4661
|
return loweredStmt{rangeFunc: &loweredRangeFunc{
|
|
3944
4662
|
value: rangeValue,
|
|
3945
4663
|
params: paramNames,
|
|
3946
4664
|
body: body,
|
|
3947
|
-
async:
|
|
4665
|
+
async: async,
|
|
3948
4666
|
returnBranch: rangeBranch,
|
|
3949
4667
|
parentBranch: parentBranch,
|
|
3950
4668
|
}}, diagnostics
|
|
@@ -3989,6 +4707,7 @@ func (o *LoweringOwner) lowerSelectStmt(ctx lowerFileContext, stmt *ast.SelectSt
|
|
|
3989
4707
|
lowered := &loweredSelect{
|
|
3990
4708
|
hasReturn: selectName + "HasReturn",
|
|
3991
4709
|
value: selectName + "Value",
|
|
4710
|
+
result: selectName + "Result",
|
|
3992
4711
|
resultType: resultType,
|
|
3993
4712
|
}
|
|
3994
4713
|
var diagnostics []Diagnostic
|
|
@@ -4025,7 +4744,7 @@ func (o *LoweringOwner) lowerSelectStmt(ctx lowerFileContext, stmt *ast.SelectSt
|
|
|
4025
4744
|
})
|
|
4026
4745
|
caseID++
|
|
4027
4746
|
case *ast.ExprStmt:
|
|
4028
|
-
channel, prelude, receiveDiagnostics := o.lowerSelectReceiveComm(ctx, nil, comm.X)
|
|
4747
|
+
channel, prelude, receiveDiagnostics := o.lowerSelectReceiveComm(ctx, nil, comm.X, lowered.result)
|
|
4029
4748
|
body, bodyDiagnostics := o.lowerStmtList(ctx.withLocalScope().withoutRangeBreak(), clause.Body)
|
|
4030
4749
|
diagnostics = append(diagnostics, receiveDiagnostics...)
|
|
4031
4750
|
diagnostics = append(diagnostics, bodyDiagnostics...)
|
|
@@ -4037,7 +4756,7 @@ func (o *LoweringOwner) lowerSelectStmt(ctx lowerFileContext, stmt *ast.SelectSt
|
|
|
4037
4756
|
})
|
|
4038
4757
|
caseID++
|
|
4039
4758
|
case *ast.AssignStmt:
|
|
4040
|
-
channel, prelude, receiveDiagnostics := o.lowerSelectReceiveComm(ctx, comm, nil)
|
|
4759
|
+
channel, prelude, receiveDiagnostics := o.lowerSelectReceiveComm(ctx, comm, nil, lowered.result)
|
|
4041
4760
|
body, bodyDiagnostics := o.lowerStmtList(ctx.withLocalScope().withoutRangeBreak(), clause.Body)
|
|
4042
4761
|
diagnostics = append(diagnostics, receiveDiagnostics...)
|
|
4043
4762
|
diagnostics = append(diagnostics, bodyDiagnostics...)
|
|
@@ -4083,11 +4802,22 @@ func stmtsEndInReturn(stmts []loweredStmt) bool {
|
|
|
4083
4802
|
return false
|
|
4084
4803
|
}
|
|
4085
4804
|
last := stmts[len(stmts)-1]
|
|
4086
|
-
|
|
4805
|
+
return stmtEndsInReturn(last)
|
|
4806
|
+
}
|
|
4807
|
+
|
|
4808
|
+
func stmtEndsInReturn(stmt loweredStmt) bool {
|
|
4809
|
+
trimmed := strings.TrimSpace(stmt.text)
|
|
4810
|
+
if strings.HasPrefix(trimmed, "return") {
|
|
4087
4811
|
return true
|
|
4088
4812
|
}
|
|
4089
|
-
if
|
|
4090
|
-
return
|
|
4813
|
+
if stmt.selectStmt != nil {
|
|
4814
|
+
return stmt.selectStmt.returns
|
|
4815
|
+
}
|
|
4816
|
+
if trimmed == "" && (stmt.hasBlock || len(stmt.children) != 0) {
|
|
4817
|
+
return stmtsEndInReturn(stmt.children)
|
|
4818
|
+
}
|
|
4819
|
+
if strings.HasPrefix(trimmed, "if ") && len(stmt.elseBody) != 0 {
|
|
4820
|
+
return stmtsEndInReturn(stmt.children) && stmtsEndInReturn(stmt.elseBody)
|
|
4091
4821
|
}
|
|
4092
4822
|
return false
|
|
4093
4823
|
}
|
|
@@ -4134,6 +4864,7 @@ func (o *LoweringOwner) lowerSelectReceiveComm(
|
|
|
4134
4864
|
ctx lowerFileContext,
|
|
4135
4865
|
assign *ast.AssignStmt,
|
|
4136
4866
|
expr ast.Expr,
|
|
4867
|
+
resultName string,
|
|
4137
4868
|
) (string, []loweredStmt, []Diagnostic) {
|
|
4138
4869
|
receiveExpr := expr
|
|
4139
4870
|
if assign != nil && len(assign.Rhs) == 1 {
|
|
@@ -4162,7 +4893,7 @@ func (o *LoweringOwner) lowerSelectReceiveComm(
|
|
|
4162
4893
|
if assign.Tok == token.DEFINE && isShortAssignTargetNew(ctx, lhs) {
|
|
4163
4894
|
prefix = "let "
|
|
4164
4895
|
}
|
|
4165
|
-
prelude = append(prelude, loweredStmt{text: prefix + left + " =
|
|
4896
|
+
prelude = append(prelude, loweredStmt{text: prefix + left + " = " + resultName + fields[idx]})
|
|
4166
4897
|
}
|
|
4167
4898
|
return channel, prelude, diagnostics
|
|
4168
4899
|
}
|
|
@@ -4177,15 +4908,24 @@ func (o *LoweringOwner) lowerSwitchStmt(ctx lowerFileContext, stmt *ast.SwitchSt
|
|
|
4177
4908
|
}
|
|
4178
4909
|
|
|
4179
4910
|
value := "true"
|
|
4911
|
+
var tagType types.Type
|
|
4180
4912
|
if stmt.Tag != nil {
|
|
4181
4913
|
var valueDiagnostics []Diagnostic
|
|
4182
4914
|
value, valueDiagnostics = o.lowerExpr(ctx, stmt.Tag)
|
|
4183
4915
|
diagnostics = append(diagnostics, valueDiagnostics...)
|
|
4184
4916
|
value = lowerConstantComparableValue(ctx, stmt.Tag, value)
|
|
4917
|
+
tagType = ctx.semPkg.source.TypesInfo.TypeOf(stmt.Tag)
|
|
4185
4918
|
} else if switchHasConstantCaseExpr(ctx, stmt) {
|
|
4186
4919
|
value = "(true as boolean)"
|
|
4187
4920
|
}
|
|
4188
4921
|
|
|
4922
|
+
compareCases := tagType != nil && isInterfaceType(tagType)
|
|
4923
|
+
compareValue := value
|
|
4924
|
+
if compareCases {
|
|
4925
|
+
compareValue = ctx.tempName("Switch")
|
|
4926
|
+
init = append(init, loweredStmt{text: "let " + compareValue + " = " + value})
|
|
4927
|
+
value = "true"
|
|
4928
|
+
}
|
|
4189
4929
|
switchIR := &loweredSwitch{value: value}
|
|
4190
4930
|
for _, raw := range stmt.Body.List {
|
|
4191
4931
|
clause, ok := raw.(*ast.CaseClause)
|
|
@@ -4207,6 +4947,11 @@ func (o *LoweringOwner) lowerSwitchStmt(ctx lowerFileContext, stmt *ast.SwitchSt
|
|
|
4207
4947
|
for _, expr := range clause.List {
|
|
4208
4948
|
lowered, exprDiagnostics := o.lowerExpr(ctx, expr)
|
|
4209
4949
|
diagnostics = append(diagnostics, exprDiagnostics...)
|
|
4950
|
+
if compareCases {
|
|
4951
|
+
sourceType := ctx.semPkg.source.TypesInfo.TypeOf(expr)
|
|
4952
|
+
lowered = o.lowerValueForTargetTypes(ctx, tagType, sourceType, lowered, shouldCloneStructValue(expr))
|
|
4953
|
+
lowered = o.runtimeOwner.QualifiedHelper(RuntimeHelperComparableEqual) + "(" + compareValue + ", " + lowered + ")"
|
|
4954
|
+
}
|
|
4210
4955
|
values = append(values, lowered)
|
|
4211
4956
|
}
|
|
4212
4957
|
switchIR.cases = append(switchIR.cases, loweredSwitchCase{
|
|
@@ -4309,7 +5054,7 @@ func (o *LoweringOwner) lowerTypeSwitchStmt(ctx lowerFileContext, stmt *ast.Type
|
|
|
4309
5054
|
if typ == nil {
|
|
4310
5055
|
tsTypes = append(tsTypes, "any")
|
|
4311
5056
|
} else {
|
|
4312
|
-
tsTypes = append(tsTypes, o.
|
|
5057
|
+
tsTypes = append(tsTypes, o.tsTypeSwitchCaseTypeFor(ctx, typ))
|
|
4313
5058
|
}
|
|
4314
5059
|
}
|
|
4315
5060
|
switchIR.cases = append(switchIR.cases, loweredTypeSwitchCase{
|
|
@@ -4323,6 +5068,15 @@ func (o *LoweringOwner) lowerTypeSwitchStmt(ctx lowerFileContext, stmt *ast.Type
|
|
|
4323
5068
|
return lowered, diagnostics
|
|
4324
5069
|
}
|
|
4325
5070
|
|
|
5071
|
+
func (o *LoweringOwner) tsTypeSwitchCaseTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
5072
|
+
if named, ok := types.Unalias(typ).(*types.Named); ok {
|
|
5073
|
+
if _, ok := named.Underlying().(*types.Interface); ok {
|
|
5074
|
+
return o.tsNonNilTypeFor(ctx, named)
|
|
5075
|
+
}
|
|
5076
|
+
}
|
|
5077
|
+
return o.tsTypeFor(ctx, typ)
|
|
5078
|
+
}
|
|
5079
|
+
|
|
4326
5080
|
func loweredStmtsUseVarRefName(stmts []loweredStmt, name string) bool {
|
|
4327
5081
|
if name == "" {
|
|
4328
5082
|
return false
|
|
@@ -4518,52 +5272,176 @@ func (o *LoweringOwner) lowerArrayEqualityExpr(ctx lowerFileContext, expr *ast.B
|
|
|
4518
5272
|
return value, true
|
|
4519
5273
|
}
|
|
4520
5274
|
|
|
4521
|
-
func (o *LoweringOwner)
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
5275
|
+
func (o *LoweringOwner) lowerComplexEqualityExpr(ctx lowerFileContext, expr *ast.BinaryExpr, left string, right string) (string, bool) {
|
|
5276
|
+
leftType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
5277
|
+
rightType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Y)
|
|
5278
|
+
if !isComplexType(leftType) || !isComplexType(rightType) {
|
|
5279
|
+
return "", false
|
|
5280
|
+
}
|
|
5281
|
+
value := o.runtimeOwner.QualifiedHelper(RuntimeHelperArrayEqual) + "(" + left + ", " + right + ")"
|
|
5282
|
+
if expr.Op == token.NEQ {
|
|
5283
|
+
value = "!" + value
|
|
5284
|
+
}
|
|
5285
|
+
return value, true
|
|
5286
|
+
}
|
|
5287
|
+
|
|
5288
|
+
func (o *LoweringOwner) lowerStringEqualityExpr(ctx lowerFileContext, expr *ast.BinaryExpr, left string, right string) (string, bool) {
|
|
5289
|
+
leftType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
5290
|
+
rightType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Y)
|
|
5291
|
+
if !isStringType(leftType) || !isStringType(rightType) {
|
|
5292
|
+
return "", false
|
|
5293
|
+
}
|
|
5294
|
+
value := o.runtimeOwner.QualifiedHelper(RuntimeHelperStringEqual) + "(" + left + ", " + right + ")"
|
|
5295
|
+
if expr.Op == token.NEQ {
|
|
5296
|
+
value = "!" + value
|
|
5297
|
+
}
|
|
5298
|
+
return value, true
|
|
5299
|
+
}
|
|
5300
|
+
|
|
5301
|
+
func (o *LoweringOwner) lowerInterfaceEqualityExpr(ctx lowerFileContext, expr *ast.BinaryExpr, left string, right string) (string, bool) {
|
|
5302
|
+
if isNilExpr(expr.X) || isNilExpr(expr.Y) {
|
|
5303
|
+
return "", false
|
|
5304
|
+
}
|
|
5305
|
+
leftType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
5306
|
+
rightType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Y)
|
|
5307
|
+
if !isInterfaceType(leftType) && !isInterfaceType(rightType) {
|
|
5308
|
+
return "", false
|
|
5309
|
+
}
|
|
5310
|
+
value := o.runtimeOwner.QualifiedHelper(RuntimeHelperComparableEqual) + "(" + left + ", " + right + ")"
|
|
5311
|
+
if expr.Op == token.NEQ {
|
|
5312
|
+
value = "!" + value
|
|
5313
|
+
}
|
|
5314
|
+
return value, true
|
|
5315
|
+
}
|
|
5316
|
+
|
|
5317
|
+
func (o *LoweringOwner) lowerStringOrderExpr(
|
|
5318
|
+
ctx lowerFileContext,
|
|
5319
|
+
expr *ast.BinaryExpr,
|
|
5320
|
+
left string,
|
|
5321
|
+
right string,
|
|
5322
|
+
leftDiagnostics []Diagnostic,
|
|
5323
|
+
rightDiagnostics []Diagnostic,
|
|
5324
|
+
) (string, []Diagnostic, bool) {
|
|
5325
|
+
leftType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
5326
|
+
rightType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Y)
|
|
5327
|
+
if !isStringType(leftType) || !isStringType(rightType) {
|
|
5328
|
+
return "", nil, false
|
|
5329
|
+
}
|
|
5330
|
+
left, leftDiagnostics = o.lowerStringOrderOperand(ctx, expr.X, left, leftDiagnostics)
|
|
5331
|
+
right, rightDiagnostics = o.lowerStringOrderOperand(ctx, expr.Y, right, rightDiagnostics)
|
|
5332
|
+
compare := o.runtimeOwner.QualifiedHelper(RuntimeHelperStringCompare) + "(" + left + ", " + right + ")"
|
|
5333
|
+
switch expr.Op {
|
|
5334
|
+
case token.LSS:
|
|
5335
|
+
return compare + " < 0", append(leftDiagnostics, rightDiagnostics...), true
|
|
5336
|
+
case token.LEQ:
|
|
5337
|
+
return compare + " <= 0", append(leftDiagnostics, rightDiagnostics...), true
|
|
5338
|
+
case token.GTR:
|
|
5339
|
+
return compare + " > 0", append(leftDiagnostics, rightDiagnostics...), true
|
|
5340
|
+
case token.GEQ:
|
|
5341
|
+
return compare + " >= 0", append(leftDiagnostics, rightDiagnostics...), true
|
|
5342
|
+
default:
|
|
5343
|
+
return "", nil, false
|
|
5344
|
+
}
|
|
5345
|
+
}
|
|
5346
|
+
|
|
5347
|
+
func (o *LoweringOwner) lowerStringOrderOperand(
|
|
5348
|
+
ctx lowerFileContext,
|
|
5349
|
+
expr ast.Expr,
|
|
5350
|
+
fallback string,
|
|
5351
|
+
fallbackDiagnostics []Diagnostic,
|
|
5352
|
+
) (string, []Diagnostic) {
|
|
5353
|
+
call, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
5354
|
+
if !ok || len(call.Args) != 1 {
|
|
5355
|
+
return fallback, fallbackDiagnostics
|
|
5356
|
+
}
|
|
5357
|
+
targetType := typeFromExpr(ctx, call.Fun)
|
|
5358
|
+
sourceType := ctx.semPkg.source.TypesInfo.TypeOf(call.Args[0])
|
|
5359
|
+
if targetType == nil || sourceType == nil || !isStringType(targetType) || !isByteSliceType(sourceType) {
|
|
5360
|
+
return fallback, fallbackDiagnostics
|
|
5361
|
+
}
|
|
5362
|
+
return o.lowerExpr(ctx, call.Args[0])
|
|
5363
|
+
}
|
|
5364
|
+
|
|
5365
|
+
func binaryOperandUsesTypeParam(ctx lowerFileContext, expr ast.Expr) bool {
|
|
5366
|
+
typ := ctx.semPkg.source.TypesInfo.TypeOf(expr)
|
|
5367
|
+
_, ok := types.Unalias(typ).(*types.TypeParam)
|
|
5368
|
+
return ok
|
|
5369
|
+
}
|
|
5370
|
+
|
|
5371
|
+
func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
5372
|
+
if value := ctx.semPkg.source.TypesInfo.Types[unwrapParenExpr(expr)].Value; value != nil && value.Kind() == constant.Complex {
|
|
5373
|
+
if constantValue, ok := lowerConstantValue(value); ok {
|
|
5374
|
+
return constantValue, nil
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5377
|
+
switch typed := expr.(type) {
|
|
5378
|
+
case *ast.BasicLit:
|
|
5379
|
+
return lowerBasicLit(typed), nil
|
|
5380
|
+
case *ast.Ident:
|
|
5381
|
+
return o.lowerIdent(ctx, typed, false), nil
|
|
5382
|
+
case *ast.BinaryExpr:
|
|
5383
|
+
if value := ctx.semPkg.source.TypesInfo.Types[typed].Value; value != nil {
|
|
5384
|
+
if (typed.Op == token.SHL || typed.Op == token.SHR) && (value.Kind() == constant.Int || value.Kind() == constant.Float) {
|
|
5385
|
+
if constantValue, ok := lowerConstantValue(value); ok {
|
|
5386
|
+
return constantValue, nil
|
|
5387
|
+
}
|
|
5388
|
+
}
|
|
5389
|
+
if constantValue, ok := lowerLargeIntegerConstantValue(value); ok {
|
|
5390
|
+
return constantValue, nil
|
|
5391
|
+
}
|
|
5392
|
+
}
|
|
5393
|
+
if isEqualityOperator(typed.Op) {
|
|
5394
|
+
if value, diagnostics, ok := o.lowerAddressEqualityExpr(ctx, typed); ok {
|
|
5395
|
+
return value, diagnostics
|
|
5396
|
+
}
|
|
5397
|
+
}
|
|
5398
|
+
left, leftDiagnostics := o.lowerExpr(ctx, typed.X)
|
|
5399
|
+
right, rightDiagnostics := o.lowerExpr(ctx, typed.Y)
|
|
5400
|
+
if _, ok := typed.X.(*ast.BinaryExpr); ok {
|
|
5401
|
+
left = "(" + left + ")"
|
|
5402
|
+
}
|
|
5403
|
+
if _, ok := typed.Y.(*ast.BinaryExpr); ok {
|
|
5404
|
+
right = "(" + right + ")"
|
|
5405
|
+
}
|
|
5406
|
+
if typed.Op == token.AND_NOT {
|
|
5407
|
+
return left + " & ~(" + right + ")", append(leftDiagnostics, rightDiagnostics...)
|
|
5408
|
+
}
|
|
5409
|
+
if isEqualityOperator(typed.Op) {
|
|
5410
|
+
if value, ok := o.lowerArrayEqualityExpr(ctx, typed, left, right); ok {
|
|
5411
|
+
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
5412
|
+
}
|
|
5413
|
+
if value, ok := o.lowerComplexEqualityExpr(ctx, typed, left, right); ok {
|
|
5414
|
+
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
5415
|
+
}
|
|
5416
|
+
if value, ok := o.lowerStringEqualityExpr(ctx, typed, left, right); ok {
|
|
5417
|
+
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
5418
|
+
}
|
|
5419
|
+
if value, ok := o.lowerInterfaceEqualityExpr(ctx, typed, left, right); ok {
|
|
5420
|
+
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
4562
5421
|
}
|
|
5422
|
+
left, right = o.lowerEqualityOperands(ctx, typed, left, right)
|
|
4563
5423
|
}
|
|
4564
5424
|
if value, ok := o.lowerWideIntegerBinaryExpr(ctx, typed, left, right); ok {
|
|
4565
5425
|
return value, append(leftDiagnostics, rightDiagnostics...)
|
|
4566
5426
|
}
|
|
5427
|
+
if typed.Op == token.QUO && isIntegerType(ctx.semPkg.source.TypesInfo.TypeOf(typed)) {
|
|
5428
|
+
return "Math.trunc(" + left + " / " + right + ")", append(leftDiagnostics, rightDiagnostics...)
|
|
5429
|
+
}
|
|
5430
|
+
if typed.Op == token.SHR {
|
|
5431
|
+
if bits, ok := unsignedIntegerBits(ctx.semPkg.source.TypesInfo.TypeOf(typed.X)); ok && bits <= 32 {
|
|
5432
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUintShr) +
|
|
5433
|
+
"(" + left + ", " + right + ", " + strconv.Itoa(bits) + ")", append(leftDiagnostics, rightDiagnostics...)
|
|
5434
|
+
}
|
|
5435
|
+
}
|
|
5436
|
+
if value, diagnostics, ok := o.lowerStringOrderExpr(ctx, typed, left, right, leftDiagnostics, rightDiagnostics); ok {
|
|
5437
|
+
return value, diagnostics
|
|
5438
|
+
}
|
|
5439
|
+
if binaryOperandUsesTypeParam(ctx, typed.X) {
|
|
5440
|
+
left = "(" + left + " as any)"
|
|
5441
|
+
}
|
|
5442
|
+
if binaryOperandUsesTypeParam(ctx, typed.Y) {
|
|
5443
|
+
right = "(" + right + " as any)"
|
|
5444
|
+
}
|
|
4567
5445
|
return left + " " + typed.Op.String() + " " + right, append(leftDiagnostics, rightDiagnostics...)
|
|
4568
5446
|
case *ast.UnaryExpr:
|
|
4569
5447
|
if typed.Op == token.AND {
|
|
@@ -4575,7 +5453,7 @@ func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
4575
5453
|
}
|
|
4576
5454
|
value, diagnostics := o.lowerExpr(ctx, typed.X)
|
|
4577
5455
|
if typed.Op == token.NOT || typed.Op == token.SUB || typed.Op == token.ADD {
|
|
4578
|
-
return typed.Op
|
|
5456
|
+
return lowerPrefixUnaryExpr(typed.Op, value), diagnostics
|
|
4579
5457
|
}
|
|
4580
5458
|
if typed.Op == token.XOR {
|
|
4581
5459
|
return "~" + value, diagnostics
|
|
@@ -4621,7 +5499,7 @@ func lowerBasicLit(lit *ast.BasicLit) string {
|
|
|
4621
5499
|
if err != nil {
|
|
4622
5500
|
return strconv.Quote(lit.Value)
|
|
4623
5501
|
}
|
|
4624
|
-
return
|
|
5502
|
+
return lowerGoStringLiteral(value)
|
|
4625
5503
|
}
|
|
4626
5504
|
if lit.Kind == token.INT && isLegacyOctalLiteral(lit.Value) {
|
|
4627
5505
|
digits := strings.TrimLeft(strings.ReplaceAll(lit.Value, "_", ""), "0")
|
|
@@ -4665,8 +5543,17 @@ func (o *LoweringOwner) lowerFuncLit(ctx lowerFileContext, lit *ast.FuncLit) (st
|
|
|
4665
5543
|
if asyncCompatibleParams || funcLiteralUsesFunctionIdentifierCall(ctx, lit) {
|
|
4666
5544
|
bodyCtx = bodyCtx.withAsyncFunction(true)
|
|
4667
5545
|
}
|
|
5546
|
+
var params []loweredParam
|
|
5547
|
+
var paramBindings []loweredStmt
|
|
5548
|
+
if signature != nil && signature.Params() != nil {
|
|
5549
|
+
for idx := range signature.Params().Len() {
|
|
5550
|
+
param := signature.Params().At(idx)
|
|
5551
|
+
params, paramBindings = o.appendLoweredParam(ctx, params, paramBindings, param, idx, asyncCompatibleParams)
|
|
5552
|
+
}
|
|
5553
|
+
}
|
|
4668
5554
|
body, diagnostics := o.lowerBlock(bodyCtx, lit.Body)
|
|
4669
5555
|
var rendered strings.Builder
|
|
5556
|
+
renderStmts(&rendered, paramBindings, 1)
|
|
4670
5557
|
renderNamedResults(&rendered, o.lowerNamedResults(ctx, signature), 1)
|
|
4671
5558
|
renderDeferStack(&rendered, deferState, 1)
|
|
4672
5559
|
renderStmts(&rendered, body, 1)
|
|
@@ -4675,21 +5562,28 @@ func (o *LoweringOwner) lowerFuncLit(ctx lowerFileContext, lit *ast.FuncLit) (st
|
|
|
4675
5562
|
if async {
|
|
4676
5563
|
prefix = "async "
|
|
4677
5564
|
}
|
|
4678
|
-
function := prefix + "(" +
|
|
5565
|
+
function := prefix + "(" + renderLoweredParams(params) + "): " +
|
|
4679
5566
|
asyncResultType(o.tsSignatureResultFor(ctx, signature), async) + " => {\n" +
|
|
4680
5567
|
rendered.String() + "}"
|
|
4681
5568
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperFunctionValue) +
|
|
4682
5569
|
"(" + function + ", " + o.runtimeFunctionTypeInfo(signature, "") + ")", async, diagnostics
|
|
4683
5570
|
}
|
|
4684
5571
|
|
|
5572
|
+
func renderLoweredParams(params []loweredParam) string {
|
|
5573
|
+
if len(params) == 0 {
|
|
5574
|
+
return ""
|
|
5575
|
+
}
|
|
5576
|
+
rendered := make([]string, 0, len(params))
|
|
5577
|
+
for _, param := range params {
|
|
5578
|
+
rendered = append(rendered, param.name+": "+param.typ)
|
|
5579
|
+
}
|
|
5580
|
+
return strings.Join(rendered, ", ")
|
|
5581
|
+
}
|
|
5582
|
+
|
|
4685
5583
|
func funcLiteralUsesFunctionIdentifierCall(ctx lowerFileContext, lit *ast.FuncLit) bool {
|
|
4686
5584
|
if lit == nil || lit.Body == nil || ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
4687
5585
|
return false
|
|
4688
5586
|
}
|
|
4689
|
-
signature, _ := ctx.semPkg.source.TypesInfo.TypeOf(lit).(*types.Signature)
|
|
4690
|
-
if signature == nil || signature.Results() == nil || signature.Results().Len() == 0 {
|
|
4691
|
-
return false
|
|
4692
|
-
}
|
|
4693
5587
|
uses := false
|
|
4694
5588
|
ast.Inspect(lit.Body, func(node ast.Node) bool {
|
|
4695
5589
|
if uses {
|
|
@@ -4760,6 +5654,9 @@ func (o *LoweringOwner) lowerIdent(ctx lowerFileContext, ident *ast.Ident, raw b
|
|
|
4760
5654
|
}
|
|
4761
5655
|
obj := objectForIdent(ctx, ident)
|
|
4762
5656
|
if alias := ctx.identAliases[obj]; alias != "" {
|
|
5657
|
+
if !raw && obj != nil && ctx.identAliasRefs[obj] && ctx.model.needsVarRef[obj] {
|
|
5658
|
+
return alias + ".value"
|
|
5659
|
+
}
|
|
4763
5660
|
return alias
|
|
4764
5661
|
}
|
|
4765
5662
|
if constObj, ok := obj.(*types.Const); ok && ctx.localAliases[obj] != "" {
|
|
@@ -4770,22 +5667,22 @@ func (o *LoweringOwner) lowerIdent(ctx lowerFileContext, ident *ast.Ident, raw b
|
|
|
4770
5667
|
if alias := ctx.localAliases[obj]; alias != "" {
|
|
4771
5668
|
if ctx.lazyPackageVars[obj] {
|
|
4772
5669
|
lazyValue := alias + "." + packageVarGetterName(value) + "()"
|
|
4773
|
-
if
|
|
4774
|
-
return lazyValue
|
|
5670
|
+
if raw {
|
|
5671
|
+
return lazyValue
|
|
4775
5672
|
}
|
|
4776
|
-
return lazyValue
|
|
5673
|
+
return o.lowerPackageVarReadValue(ctx, obj, lazyValue)
|
|
5674
|
+
}
|
|
5675
|
+
if raw {
|
|
5676
|
+
return alias + "." + value
|
|
4777
5677
|
}
|
|
4778
|
-
return alias
|
|
5678
|
+
return o.lowerPackageVarReadValue(ctx, obj, alias+"."+value)
|
|
4779
5679
|
}
|
|
4780
5680
|
if raw {
|
|
4781
5681
|
return value
|
|
4782
5682
|
}
|
|
4783
5683
|
if ctx.lazyPackageVars[obj] {
|
|
4784
5684
|
lazyValue := packageVarGetterName(value) + "()"
|
|
4785
|
-
|
|
4786
|
-
return lazyValue + ".value"
|
|
4787
|
-
}
|
|
4788
|
-
return lazyValue
|
|
5685
|
+
return o.lowerPackageVarReadValue(ctx, obj, lazyValue)
|
|
4789
5686
|
}
|
|
4790
5687
|
if obj != nil && ctx.model.needsVarRef[obj] {
|
|
4791
5688
|
return value + ".value"
|
|
@@ -4793,6 +5690,17 @@ func (o *LoweringOwner) lowerIdent(ctx lowerFileContext, ident *ast.Ident, raw b
|
|
|
4793
5690
|
return value
|
|
4794
5691
|
}
|
|
4795
5692
|
|
|
5693
|
+
func (o *LoweringOwner) lowerPackageVarReadValue(ctx lowerFileContext, obj types.Object, value string) string {
|
|
5694
|
+
if obj == nil || ctx.model == nil || !ctx.model.needsVarRef[obj] {
|
|
5695
|
+
return value
|
|
5696
|
+
}
|
|
5697
|
+
if varObj, ok := obj.(*types.Var); ok && packageVarReadNeedsPointerValue(varObj.Type()) {
|
|
5698
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue) +
|
|
5699
|
+
"<" + o.tsNonNilTypeFor(ctx, varObj.Type()) + ">(" + value + ")"
|
|
5700
|
+
}
|
|
5701
|
+
return value + ".value"
|
|
5702
|
+
}
|
|
5703
|
+
|
|
4796
5704
|
func objectForIdent(ctx lowerFileContext, ident *ast.Ident) types.Object {
|
|
4797
5705
|
if ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
4798
5706
|
return nil
|
|
@@ -4820,6 +5728,28 @@ func objectForValueExpr(ctx lowerFileContext, expr ast.Expr) types.Object {
|
|
|
4820
5728
|
}
|
|
4821
5729
|
}
|
|
4822
5730
|
|
|
5731
|
+
func objectNeedsVarRef(ctx lowerFileContext, obj types.Object) bool {
|
|
5732
|
+
if obj == nil || ctx.model == nil {
|
|
5733
|
+
return false
|
|
5734
|
+
}
|
|
5735
|
+
if ctx.model.needsVarRef[obj] {
|
|
5736
|
+
return true
|
|
5737
|
+
}
|
|
5738
|
+
if obj.Pkg() == nil {
|
|
5739
|
+
return false
|
|
5740
|
+
}
|
|
5741
|
+
semPkg := ctx.model.packages[obj.Pkg().Path()]
|
|
5742
|
+
if semPkg == nil {
|
|
5743
|
+
return false
|
|
5744
|
+
}
|
|
5745
|
+
for _, value := range semPkg.values {
|
|
5746
|
+
if value.name == obj.Name() && ctx.model.needsVarRef[value.object] {
|
|
5747
|
+
return true
|
|
5748
|
+
}
|
|
5749
|
+
}
|
|
5750
|
+
return false
|
|
5751
|
+
}
|
|
5752
|
+
|
|
4823
5753
|
func (o *LoweringOwner) lowerCallExpr(ctx lowerFileContext, expr *ast.CallExpr) (string, []Diagnostic) {
|
|
4824
5754
|
if ident, ok := expr.Fun.(*ast.Ident); ok && isBuiltinCallTarget(ctx, ident) {
|
|
4825
5755
|
switch ident.Name {
|
|
@@ -4846,6 +5776,22 @@ func (o *LoweringOwner) lowerCallExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
4846
5776
|
}
|
|
4847
5777
|
return o.runtimeOwner.QualifiedHelper(helper) + "(" + strings.Join(args, ", ") + ")", diagnostics
|
|
4848
5778
|
case "append":
|
|
5779
|
+
if len(expr.Args) > 0 {
|
|
5780
|
+
if slice, ok := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(expr.Args[0])).Underlying().(*types.Slice); ok {
|
|
5781
|
+
for idx := 1; idx < len(args); idx++ {
|
|
5782
|
+
if expr.Ellipsis != token.NoPos && idx == len(args)-1 {
|
|
5783
|
+
continue
|
|
5784
|
+
}
|
|
5785
|
+
args[idx] = o.lowerValueForTargetTypes(
|
|
5786
|
+
ctx,
|
|
5787
|
+
slice.Elem(),
|
|
5788
|
+
ctx.semPkg.source.TypesInfo.TypeOf(expr.Args[idx]),
|
|
5789
|
+
args[idx],
|
|
5790
|
+
false,
|
|
5791
|
+
)
|
|
5792
|
+
}
|
|
5793
|
+
}
|
|
5794
|
+
}
|
|
4849
5795
|
if expr.Ellipsis != token.NoPos && len(args) > 1 {
|
|
4850
5796
|
last := len(args) - 1
|
|
4851
5797
|
spread := args[last]
|
|
@@ -4854,7 +5800,13 @@ func (o *LoweringOwner) lowerCallExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
4854
5800
|
}
|
|
4855
5801
|
args[last] = "...(" + spread + " ?? [])"
|
|
4856
5802
|
}
|
|
4857
|
-
|
|
5803
|
+
appendHelper := o.runtimeOwner.QualifiedHelper(RuntimeHelperAppend)
|
|
5804
|
+
if len(args) > 0 && args[0] == "null" {
|
|
5805
|
+
if slice, ok := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(expr)).Underlying().(*types.Slice); ok {
|
|
5806
|
+
appendHelper += "<" + o.tsTypeFor(ctx, slice.Elem()) + ">"
|
|
5807
|
+
}
|
|
5808
|
+
}
|
|
5809
|
+
return appendHelper + "(" + strings.Join(args, ", ") + ")", diagnostics
|
|
4858
5810
|
case "cap":
|
|
4859
5811
|
if len(expr.Args) == 1 {
|
|
4860
5812
|
args[0] = o.lowerArrayPointerTarget(ctx, args[0], ctx.semPkg.source.TypesInfo.TypeOf(expr.Args[0]))
|
|
@@ -4906,7 +5858,7 @@ func (o *LoweringOwner) lowerCallExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
4906
5858
|
if typeParam := receiverTypeParam(selection.Recv()); typeParam != nil {
|
|
4907
5859
|
receiverExpr, receiverDiagnostics := o.lowerExpr(ctx, fun.X)
|
|
4908
5860
|
diagnostics = append(diagnostics, receiverDiagnostics...)
|
|
4909
|
-
if !
|
|
5861
|
+
if !typeParamInScope(ctx, typeParam) {
|
|
4910
5862
|
call := receiverExpr + "." + fun.Sel.Name + "(" + strings.Join(args, ", ") + ")"
|
|
4911
5863
|
return o.awaitCallIfNeeded(ctx, fun, call), diagnostics
|
|
4912
5864
|
}
|
|
@@ -4914,11 +5866,14 @@ func (o *LoweringOwner) lowerCallExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
4914
5866
|
call := o.runtimeOwner.QualifiedHelper(RuntimeHelperCallGenericMethod) + "(" + strings.Join(methodArgs, ", ") + ")"
|
|
4915
5867
|
return o.awaitCallIfNeeded(ctx, fun, call), diagnostics
|
|
4916
5868
|
}
|
|
4917
|
-
receiver :=
|
|
5869
|
+
receiver := methodReceiverNamedType(selection.Obj())
|
|
5870
|
+
if receiver == nil {
|
|
5871
|
+
receiver = receiverNamedType(selection.Recv())
|
|
5872
|
+
}
|
|
4918
5873
|
if namedNonInterfaceNonStructType(receiver) {
|
|
4919
5874
|
return o.lowerNamedReceiverMethodCall(ctx, fun, args, diagnostics)
|
|
4920
5875
|
}
|
|
4921
|
-
if call, callDiagnostics, ok := o.
|
|
5876
|
+
if call, callDiagnostics, ok := o.lowerPointerReceiverMethodCall(ctx, fun, selection, args); ok {
|
|
4922
5877
|
return o.awaitCallIfNeeded(ctx, fun, call), append(diagnostics, callDiagnostics...)
|
|
4923
5878
|
}
|
|
4924
5879
|
receiverExpr, receiverDiagnostics := o.lowerMethodReceiverExpr(ctx, fun.X, selection)
|
|
@@ -5024,6 +5979,7 @@ func (o *LoweringOwner) lowerCallArgs(
|
|
|
5024
5979
|
lowered = o.lowerCallArgForTarget(ctx, arg, params.At(idx).Type(), lowered, overrideCall)
|
|
5025
5980
|
} else if expr.Ellipsis != token.NoPos && idx == len(expr.Args)-1 {
|
|
5026
5981
|
lowered = o.lowerCallArgForTarget(ctx, arg, params.At(fixedCount).Type(), lowered, overrideCall)
|
|
5982
|
+
lowered = "...(" + lowered + " ?? [])"
|
|
5027
5983
|
} else {
|
|
5028
5984
|
lowered = o.lowerCallArgForTarget(ctx, arg, targetType, lowered, overrideCall)
|
|
5029
5985
|
}
|
|
@@ -5107,19 +6063,41 @@ func (o *LoweringOwner) lowerTupleCallArgs(
|
|
|
5107
6063
|
parts = append(parts, converted)
|
|
5108
6064
|
}
|
|
5109
6065
|
if !changed {
|
|
5110
|
-
return []string{"...(" + value + ")"}, diagnostics, true
|
|
6066
|
+
return []string{"...(" + o.parenthesizedTupleCast(ctx, value, params) + ")"}, diagnostics, true
|
|
5111
6067
|
}
|
|
5112
6068
|
temp := ctx.tempName("TupleArg")
|
|
5113
6069
|
for idx, part := range parts {
|
|
5114
6070
|
parts[idx] = strings.ReplaceAll(part, "__goscriptTupleArg", temp)
|
|
5115
6071
|
}
|
|
5116
|
-
body := "const " + temp + " = " + value + "; return
|
|
6072
|
+
body := "const " + temp + " = " + value + "; return " + o.tupleLiteralCast(ctx, params, parts)
|
|
5117
6073
|
if strings.Contains(value, "await ") {
|
|
5118
6074
|
return []string{"...(await (async () => { " + body + " })())"}, diagnostics, true
|
|
5119
6075
|
}
|
|
5120
6076
|
return []string{"...(() => { " + body + " })()"}, diagnostics, true
|
|
5121
6077
|
}
|
|
5122
6078
|
|
|
6079
|
+
func (o *LoweringOwner) parenthesizedTupleCast(ctx lowerFileContext, value string, params *types.Tuple) string {
|
|
6080
|
+
if strings.HasPrefix(value, "await ") {
|
|
6081
|
+
return "(" + value + ") as " + o.tupleTypeForParams(ctx, params)
|
|
6082
|
+
}
|
|
6083
|
+
return value + " as " + o.tupleTypeForParams(ctx, params)
|
|
6084
|
+
}
|
|
6085
|
+
|
|
6086
|
+
func (o *LoweringOwner) tupleLiteralCast(ctx lowerFileContext, params *types.Tuple, parts []string) string {
|
|
6087
|
+
return "[" + strings.Join(parts, ", ") + "] as " + o.tupleTypeForParams(ctx, params)
|
|
6088
|
+
}
|
|
6089
|
+
|
|
6090
|
+
func (o *LoweringOwner) tupleTypeForParams(ctx lowerFileContext, params *types.Tuple) string {
|
|
6091
|
+
if params == nil || params.Len() == 0 {
|
|
6092
|
+
return "[]"
|
|
6093
|
+
}
|
|
6094
|
+
parts := make([]string, 0, params.Len())
|
|
6095
|
+
for v := range params.Variables() {
|
|
6096
|
+
parts = append(parts, o.tsTypeFor(ctx, v.Type()))
|
|
6097
|
+
}
|
|
6098
|
+
return "[" + strings.Join(parts, ", ") + "]"
|
|
6099
|
+
}
|
|
6100
|
+
|
|
5123
6101
|
func (o *LoweringOwner) lowerFixedCallArgs(
|
|
5124
6102
|
ctx lowerFileContext,
|
|
5125
6103
|
exprs []ast.Expr,
|
|
@@ -5153,7 +6131,7 @@ func (o *LoweringOwner) lowerCallArgForTarget(
|
|
|
5153
6131
|
value = o.lowerValueForTarget(ctx, expr, targetType, value)
|
|
5154
6132
|
sourceType := ctx.semPkg.source.TypesInfo.TypeOf(expr)
|
|
5155
6133
|
if overrideCall && isNonEmptyInterfaceType(targetType) && (isInterfaceType(sourceType) || isNilableType(sourceType)) {
|
|
5156
|
-
return o.runtimeOwner.QualifiedHelper(
|
|
6134
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValueOrNil) + "(" + value + ")!"
|
|
5157
6135
|
}
|
|
5158
6136
|
return value
|
|
5159
6137
|
}
|
|
@@ -5293,7 +6271,7 @@ func (o *LoweringOwner) lowerMakeExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
5293
6271
|
args = append(args, "() => "+o.lowerZeroValueExprFor(ctx, typed.Elem()))
|
|
5294
6272
|
}
|
|
5295
6273
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperMakeSlice) +
|
|
5296
|
-
"<" + o.
|
|
6274
|
+
"<" + o.tsSliceElemTypeFor(ctx, typed.Elem()) + ">(" + strings.Join(args, ", ") + ")", diagnostics
|
|
5297
6275
|
case *types.Map:
|
|
5298
6276
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperMakeMap) +
|
|
5299
6277
|
"<" + o.tsTypeFor(ctx, typed.Key()) + ", " + o.tsTypeFor(ctx, typed.Elem()) + ">()", nil
|
|
@@ -5321,7 +6299,8 @@ func (o *LoweringOwner) lowerNewExpr(ctx lowerFileContext, expr *ast.CallExpr) (
|
|
|
5321
6299
|
if named := namedStructType(typ); named != nil {
|
|
5322
6300
|
return "new " + o.namedTypeExpr(ctx, named) + "()", nil
|
|
5323
6301
|
}
|
|
5324
|
-
return o.runtimeOwner.QualifiedHelper(RuntimeHelperVarRef) +
|
|
6302
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperVarRef) +
|
|
6303
|
+
"<" + o.tsTypeFor(ctx, typ) + ">(" + o.lowerDeclarationZeroValueExpr(ctx, typ) + ")", nil
|
|
5325
6304
|
}
|
|
5326
6305
|
|
|
5327
6306
|
func (o *LoweringOwner) lowerConversionExpr(
|
|
@@ -5339,12 +6318,17 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
5339
6318
|
return value, append(diagnostics, addressDiagnostics...)
|
|
5340
6319
|
}
|
|
5341
6320
|
}
|
|
6321
|
+
if helper, addressDiagnostics, ok := o.lowerReflectHeaderPointerConversion(ctx, targetType, expr.Args[0]); ok {
|
|
6322
|
+
return helper, append(diagnostics, addressDiagnostics...)
|
|
6323
|
+
}
|
|
6324
|
+
if helper, addressDiagnostics, ok := o.lowerUnsafeArrayPointerConversion(ctx, targetType, expr.Args[0]); ok {
|
|
6325
|
+
return helper, append(diagnostics, addressDiagnostics...)
|
|
6326
|
+
}
|
|
5342
6327
|
if isUnsafePointerType(targetType) {
|
|
5343
6328
|
return "(" + value + " as any)", diagnostics
|
|
5344
6329
|
}
|
|
5345
6330
|
if isNilExpr(expr.Args[0]) && isPointerType(targetType) {
|
|
5346
|
-
return
|
|
5347
|
-
"(" + strconv.Quote(goRuntimeTypeString(targetType)) + ")", diagnostics
|
|
6331
|
+
return "null", diagnostics
|
|
5348
6332
|
}
|
|
5349
6333
|
if isInterfaceType(targetType) {
|
|
5350
6334
|
return o.lowerValueForTarget(ctx, expr.Args[0], targetType, value), diagnostics
|
|
@@ -5402,6 +6386,13 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
5402
6386
|
return result, diagnostics
|
|
5403
6387
|
}
|
|
5404
6388
|
}
|
|
6389
|
+
if target := pointerToNamedStructType(targetType); target != nil {
|
|
6390
|
+
source := pointerToNamedStructType(sourceType)
|
|
6391
|
+
if source != nil && !types.Identical(target, source) &&
|
|
6392
|
+
types.IdenticalIgnoreTags(target.Underlying(), source.Underlying()) {
|
|
6393
|
+
return "(" + value + " as unknown as " + o.tsTypeFor(ctx, targetType) + ")", diagnostics
|
|
6394
|
+
}
|
|
6395
|
+
}
|
|
5405
6396
|
if conversion, ok := o.lowerNamedStructConversion(ctx, expr.Args[0], targetType, sourceType, value); ok {
|
|
5406
6397
|
return renderNamedStructConversion(conversion), diagnostics
|
|
5407
6398
|
}
|
|
@@ -5421,6 +6412,9 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
5421
6412
|
return value, diagnostics
|
|
5422
6413
|
}
|
|
5423
6414
|
if isNumericType(targetType) {
|
|
6415
|
+
if isFloatType(targetType) {
|
|
6416
|
+
return value, diagnostics
|
|
6417
|
+
}
|
|
5424
6418
|
if bits, ok := unsignedIntegerBits(targetType); ok {
|
|
5425
6419
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint) +
|
|
5426
6420
|
"(" + value + ", " + strconv.Itoa(bits) + ")", diagnostics
|
|
@@ -5440,45 +6434,64 @@ func (o *LoweringOwner) lowerWideIntegerBinaryExpr(ctx lowerFileContext, expr *a
|
|
|
5440
6434
|
if !resultWide && !leftWide {
|
|
5441
6435
|
return "", false
|
|
5442
6436
|
}
|
|
6437
|
+
signed := isFixedSignedWideIntegerType(ctx.semPkg.source.TypesInfo.TypeOf(expr)) ||
|
|
6438
|
+
isFixedSignedWideIntegerType(ctx.semPkg.source.TypesInfo.TypeOf(expr.X))
|
|
5443
6439
|
switch expr.Op {
|
|
5444
6440
|
case token.SHL, token.SHR:
|
|
5445
6441
|
helper := RuntimeHelperUint64Shr
|
|
5446
6442
|
if expr.Op == token.SHL {
|
|
5447
6443
|
helper = RuntimeHelperUint64Shl
|
|
5448
6444
|
}
|
|
6445
|
+
if signed {
|
|
6446
|
+
helper = RuntimeHelperInt64Shr
|
|
6447
|
+
if expr.Op == token.SHL {
|
|
6448
|
+
helper = RuntimeHelperInt64Shl
|
|
6449
|
+
}
|
|
6450
|
+
}
|
|
5449
6451
|
if _, ok := constantShiftAmount(ctx, expr.Y); !ok {
|
|
5450
6452
|
return o.runtimeOwner.QualifiedHelper(helper) + "(" + left + ", " + right + ")", true
|
|
5451
6453
|
}
|
|
5452
6454
|
amount, ok := constantShiftAmount(ctx, expr.Y)
|
|
5453
|
-
if ok && amount >= 32 && expr.Op == token.SHL {
|
|
6455
|
+
if ok && amount >= 32 && expr.Op == token.SHL && !signed {
|
|
5454
6456
|
base := o.lowerWideShiftLeftOperand(ctx, expr.X, left)
|
|
5455
6457
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64Mul) +
|
|
5456
6458
|
"(" + base + ", " + shiftMultiplier(amount) + ")", true
|
|
5457
6459
|
}
|
|
5458
6460
|
return o.runtimeOwner.QualifiedHelper(helper) + "(" + left + ", " + right + ")", true
|
|
5459
6461
|
case token.MUL:
|
|
5460
|
-
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64Mul) + "(" + left + ", " + right + ")", true
|
|
6462
|
+
return o.runtimeOwner.QualifiedHelper(wideIntegerHelper(signed, RuntimeHelperUint64Mul, RuntimeHelperInt64Mul)) + "(" + left + ", " + right + ")", true
|
|
6463
|
+
case token.QUO:
|
|
6464
|
+
return o.runtimeOwner.QualifiedHelper(wideIntegerHelper(signed, RuntimeHelperUint64Div, RuntimeHelperInt64Div)) + "(" + left + ", " + right + ")", true
|
|
6465
|
+
case token.REM:
|
|
6466
|
+
return o.runtimeOwner.QualifiedHelper(wideIntegerHelper(signed, RuntimeHelperUint64Mod, RuntimeHelperInt64Mod)) + "(" + left + ", " + right + ")", true
|
|
5461
6467
|
case token.ADD:
|
|
5462
|
-
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64Add) + "(" + left + ", " + right + ")", true
|
|
6468
|
+
return o.runtimeOwner.QualifiedHelper(wideIntegerHelper(signed, RuntimeHelperUint64Add, RuntimeHelperInt64Add)) + "(" + left + ", " + right + ")", true
|
|
5463
6469
|
case token.SUB:
|
|
5464
|
-
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64Sub) + "(" + left + ", " + right + ")", true
|
|
6470
|
+
return o.runtimeOwner.QualifiedHelper(wideIntegerHelper(signed, RuntimeHelperUint64Sub, RuntimeHelperInt64Sub)) + "(" + left + ", " + right + ")", true
|
|
5465
6471
|
case token.AND:
|
|
5466
|
-
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64And) + "(" + left + ", " + right + ")", true
|
|
6472
|
+
return o.runtimeOwner.QualifiedHelper(wideIntegerHelper(signed, RuntimeHelperUint64And, RuntimeHelperInt64And)) + "(" + left + ", " + right + ")", true
|
|
5467
6473
|
case token.XOR:
|
|
5468
|
-
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64Xor) + "(" + left + ", " + right + ")", true
|
|
6474
|
+
return o.runtimeOwner.QualifiedHelper(wideIntegerHelper(signed, RuntimeHelperUint64Xor, RuntimeHelperInt64Xor)) + "(" + left + ", " + right + ")", true
|
|
5469
6475
|
case token.OR:
|
|
5470
6476
|
shift, ok := wideLeftShiftExpr(ctx, expr.X)
|
|
5471
|
-
if ok {
|
|
6477
|
+
if ok && !signed {
|
|
5472
6478
|
if bits, ok := lowIntegerBits(ctx, expr.Y); ok && bits <= shift {
|
|
5473
6479
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64Add) + "(" + left + ", " + right + ")", true
|
|
5474
6480
|
}
|
|
5475
6481
|
}
|
|
5476
|
-
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64Or) + "(" + left + ", " + right + ")", true
|
|
6482
|
+
return o.runtimeOwner.QualifiedHelper(wideIntegerHelper(signed, RuntimeHelperUint64Or, RuntimeHelperInt64Or)) + "(" + left + ", " + right + ")", true
|
|
5477
6483
|
default:
|
|
5478
6484
|
return "", false
|
|
5479
6485
|
}
|
|
5480
6486
|
}
|
|
5481
6487
|
|
|
6488
|
+
func wideIntegerHelper(signed bool, unsigned RuntimeHelper, signedHelper RuntimeHelper) RuntimeHelper {
|
|
6489
|
+
if signed {
|
|
6490
|
+
return signedHelper
|
|
6491
|
+
}
|
|
6492
|
+
return unsigned
|
|
6493
|
+
}
|
|
6494
|
+
|
|
5482
6495
|
func (o *LoweringOwner) lowerWideShiftLeftOperand(ctx lowerFileContext, expr ast.Expr, fallback string) string {
|
|
5483
6496
|
call, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
5484
6497
|
if !ok || len(call.Args) != 1 {
|
|
@@ -5647,7 +6660,10 @@ func (o *LoweringOwner) lowerNamedReceiverMethodCall(
|
|
|
5647
6660
|
diagnostics []Diagnostic,
|
|
5648
6661
|
) (string, []Diagnostic) {
|
|
5649
6662
|
selection := ctx.semPkg.source.TypesInfo.Selections[selector]
|
|
5650
|
-
receiver :=
|
|
6663
|
+
receiver := methodReceiverNamedType(selection.Obj())
|
|
6664
|
+
if receiver == nil {
|
|
6665
|
+
receiver = selectedReceiverNamedType(ctx.semPkg.source, selector, selection)
|
|
6666
|
+
}
|
|
5651
6667
|
receiverExpr, receiverDiagnostics := o.lowerNamedReceiverForMethod(ctx, selector.X, selection)
|
|
5652
6668
|
diagnostics = append(diagnostics, receiverDiagnostics...)
|
|
5653
6669
|
allArgs := append([]string{receiverExpr}, args...)
|
|
@@ -5655,7 +6671,7 @@ func (o *LoweringOwner) lowerNamedReceiverMethodCall(
|
|
|
5655
6671
|
return o.awaitCallIfNeeded(ctx, selector, call), diagnostics
|
|
5656
6672
|
}
|
|
5657
6673
|
|
|
5658
|
-
func (o *LoweringOwner)
|
|
6674
|
+
func (o *LoweringOwner) lowerPointerReceiverMethodCall(
|
|
5659
6675
|
ctx lowerFileContext,
|
|
5660
6676
|
selector *ast.SelectorExpr,
|
|
5661
6677
|
selection *types.Selection,
|
|
@@ -5668,9 +6684,6 @@ func (o *LoweringOwner) lowerNilablePointerReceiverMethodCall(
|
|
|
5668
6684
|
if method == nil {
|
|
5669
6685
|
return "", nil, false
|
|
5670
6686
|
}
|
|
5671
|
-
if !methodAllowsNilReceiver(ctx, method) {
|
|
5672
|
-
return "", nil, false
|
|
5673
|
-
}
|
|
5674
6687
|
signature, _ := method.Type().(*types.Signature)
|
|
5675
6688
|
if signature == nil || signature.Recv() == nil {
|
|
5676
6689
|
return "", nil, false
|
|
@@ -5783,8 +6796,12 @@ func (o *LoweringOwner) lowerNamedReceiverForMethod(
|
|
|
5783
6796
|
}
|
|
5784
6797
|
return o.lowerAddressExpr(ctx, expr)
|
|
5785
6798
|
}
|
|
5786
|
-
receiver, diagnostics := o.
|
|
5787
|
-
|
|
6799
|
+
receiver, diagnostics := o.lowerMethodReceiverExpr(ctx, expr, selection)
|
|
6800
|
+
selectedType := ctx.semPkg.source.TypesInfo.TypeOf(expr)
|
|
6801
|
+
if index := selection.Index(); len(index) > 1 && !o.receiverUsesOverridePackage(selectedType) {
|
|
6802
|
+
selectedType = promotedMethodReceiverType(selectedType, index[:len(index)-1])
|
|
6803
|
+
}
|
|
6804
|
+
if receiverType != nil && isPointerType(selectedType) {
|
|
5788
6805
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue) + "<" + o.tsTypeFor(ctx, receiverType) + ">(" + receiver + ")", diagnostics
|
|
5789
6806
|
}
|
|
5790
6807
|
return receiver, diagnostics
|
|
@@ -5793,17 +6810,27 @@ func (o *LoweringOwner) lowerNamedReceiverForMethod(
|
|
|
5793
6810
|
func (o *LoweringOwner) lowerSelectorExpr(ctx lowerFileContext, expr *ast.SelectorExpr) (string, []Diagnostic) {
|
|
5794
6811
|
if ident, ok := expr.X.(*ast.Ident); ok {
|
|
5795
6812
|
if pkgName, _ := objectForIdent(ctx, ident).(*types.PkgName); pkgName != nil {
|
|
5796
|
-
if alias := ctx
|
|
5797
|
-
|
|
6813
|
+
if alias := importAliasForPkgName(ctx, pkgName); alias != "" {
|
|
6814
|
+
value := alias + "." + expr.Sel.Name
|
|
6815
|
+
obj, _ := ctx.semPkg.source.TypesInfo.Uses[expr.Sel].(*types.Var)
|
|
6816
|
+
if obj != nil && packageVarReadNeedsPointerValue(obj.Type()) {
|
|
6817
|
+
value = o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue) +
|
|
6818
|
+
"<" + o.tsNonNilTypeFor(ctx, obj.Type()) + ">(" + value + ")"
|
|
6819
|
+
}
|
|
6820
|
+
return value, nil
|
|
5798
6821
|
}
|
|
5799
6822
|
}
|
|
5800
6823
|
}
|
|
5801
6824
|
if selection := ctx.semPkg.source.TypesInfo.Selections[expr]; selection != nil {
|
|
5802
6825
|
switch selection.Kind() {
|
|
5803
6826
|
case types.MethodVal:
|
|
5804
|
-
|
|
6827
|
+
namedReceiver := methodReceiverNamedType(selection.Obj())
|
|
6828
|
+
if namedReceiver == nil {
|
|
6829
|
+
namedReceiver = selectedReceiverNamedType(ctx.semPkg.source, expr, selection)
|
|
6830
|
+
}
|
|
6831
|
+
if namedNonInterfaceNonStructType(namedReceiver) {
|
|
5805
6832
|
receiverExpr, diagnostics := o.lowerNamedReceiverForMethod(ctx, expr.X, selection)
|
|
5806
|
-
methodExpr := o.methodFunctionExpr(ctx,
|
|
6833
|
+
methodExpr := o.methodFunctionExpr(ctx, namedReceiver, selection.Obj(), expr.Sel.Name)
|
|
5807
6834
|
return o.lowerMethodValueClosure(ctx, selection, receiverExpr, methodExpr, true), diagnostics
|
|
5808
6835
|
}
|
|
5809
6836
|
receiver, diagnostics := o.lowerMethodReceiverExpr(ctx, expr.X, selection)
|
|
@@ -5818,9 +6845,41 @@ func (o *LoweringOwner) lowerSelectorExpr(ctx lowerFileContext, expr *ast.Select
|
|
|
5818
6845
|
}
|
|
5819
6846
|
}
|
|
5820
6847
|
left, diagnostics := o.lowerExpr(ctx, expr.X)
|
|
6848
|
+
left = parenthesizeAwaitedExpr(left)
|
|
5821
6849
|
return left + "." + expr.Sel.Name, diagnostics
|
|
5822
6850
|
}
|
|
5823
6851
|
|
|
6852
|
+
func packageVarSelectorNeedsPointerValue(ctx lowerFileContext, expr ast.Expr) bool {
|
|
6853
|
+
selector, ok := ast.Unparen(expr).(*ast.SelectorExpr)
|
|
6854
|
+
if !ok || ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
6855
|
+
return false
|
|
6856
|
+
}
|
|
6857
|
+
if selection := ctx.semPkg.source.TypesInfo.Selections[selector]; selection != nil {
|
|
6858
|
+
return false
|
|
6859
|
+
}
|
|
6860
|
+
ident, ok := ast.Unparen(selector.X).(*ast.Ident)
|
|
6861
|
+
if !ok {
|
|
6862
|
+
return false
|
|
6863
|
+
}
|
|
6864
|
+
pkgName, _ := objectForIdent(ctx, ident).(*types.PkgName)
|
|
6865
|
+
if importAliasForPkgName(ctx, pkgName) == "" {
|
|
6866
|
+
return false
|
|
6867
|
+
}
|
|
6868
|
+
obj, _ := ctx.semPkg.source.TypesInfo.Uses[selector.Sel].(*types.Var)
|
|
6869
|
+
return obj != nil && packageVarReadNeedsPointerValue(obj.Type())
|
|
6870
|
+
}
|
|
6871
|
+
|
|
6872
|
+
func packageVarReadNeedsPointerValue(typ types.Type) bool {
|
|
6873
|
+
if typ == nil || isPointerType(typ) {
|
|
6874
|
+
return false
|
|
6875
|
+
}
|
|
6876
|
+
if isStructValueType(typ) {
|
|
6877
|
+
return true
|
|
6878
|
+
}
|
|
6879
|
+
_, ok := types.Unalias(typ).Underlying().(*types.Array)
|
|
6880
|
+
return ok
|
|
6881
|
+
}
|
|
6882
|
+
|
|
5824
6883
|
func (o *LoweringOwner) packageVarSetterForAssignment(ctx lowerFileContext, expr ast.Expr) (string, bool) {
|
|
5825
6884
|
if ident, ok := unwrapParenExpr(expr).(*ast.Ident); ok {
|
|
5826
6885
|
obj, _ := objectForIdent(ctx, ident).(*types.Var)
|
|
@@ -5845,7 +6904,7 @@ func (o *LoweringOwner) packageVarSetterForAssignment(ctx lowerFileContext, expr
|
|
|
5845
6904
|
if pkgName == nil {
|
|
5846
6905
|
return "", false
|
|
5847
6906
|
}
|
|
5848
|
-
alias := ctx
|
|
6907
|
+
alias := importAliasForPkgName(ctx, pkgName)
|
|
5849
6908
|
if alias == "" {
|
|
5850
6909
|
return "", false
|
|
5851
6910
|
}
|
|
@@ -5856,6 +6915,36 @@ func (o *LoweringOwner) packageVarSetterForAssignment(ctx lowerFileContext, expr
|
|
|
5856
6915
|
return alias + "." + packageVarSetterName(selector.Sel.Name), true
|
|
5857
6916
|
}
|
|
5858
6917
|
|
|
6918
|
+
func (o *LoweringOwner) packageVarAssignmentValue(
|
|
6919
|
+
ctx lowerFileContext,
|
|
6920
|
+
lhs ast.Expr,
|
|
6921
|
+
targetType types.Type,
|
|
6922
|
+
right string,
|
|
6923
|
+
tok token.Token,
|
|
6924
|
+
) (string, bool) {
|
|
6925
|
+
if tok == token.ASSIGN {
|
|
6926
|
+
return right, true
|
|
6927
|
+
}
|
|
6928
|
+
left, diagnostics := o.lowerExpr(ctx, lhs)
|
|
6929
|
+
if len(diagnostics) != 0 {
|
|
6930
|
+
return "", false
|
|
6931
|
+
}
|
|
6932
|
+
if tok == token.AND_NOT_ASSIGN {
|
|
6933
|
+
return left + " & ~(" + right + ")", true
|
|
6934
|
+
}
|
|
6935
|
+
if helper, ok := wideIntegerAssignHelper(targetType, tok); ok {
|
|
6936
|
+
return o.runtimeOwner.QualifiedHelper(helper) + "(" + left + ", " + right + ")", true
|
|
6937
|
+
}
|
|
6938
|
+
if value, ok := integerQuotientAssignValueExpr(targetType, left, right, tok); ok {
|
|
6939
|
+
return value, true
|
|
6940
|
+
}
|
|
6941
|
+
op := tok.String()
|
|
6942
|
+
if before, ok := strings.CutSuffix(op, "="); ok {
|
|
6943
|
+
op = before
|
|
6944
|
+
}
|
|
6945
|
+
return left + " " + op + " " + right, true
|
|
6946
|
+
}
|
|
6947
|
+
|
|
5859
6948
|
func (o *LoweringOwner) tsPackageVarSetterValueTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
5860
6949
|
if signature := unnamedSignatureForType(typ); signature != nil {
|
|
5861
6950
|
return o.tsAsyncCompatibleFunctionTypeFor(ctx, signature)
|
|
@@ -5870,25 +6959,28 @@ func (o *LoweringOwner) lowerFieldSelectionExpr(
|
|
|
5870
6959
|
address bool,
|
|
5871
6960
|
) (string, []Diagnostic) {
|
|
5872
6961
|
receiver, diagnostics := o.lowerFieldReceiverExpr(ctx, expr.X)
|
|
6962
|
+
receiver = parenthesizeAwaitedExpr(receiver)
|
|
5873
6963
|
index := selection.Index()
|
|
5874
6964
|
if len(index) == 0 {
|
|
6965
|
+
fieldName := tsStructFieldName(expr.Sel.Name, 0)
|
|
5875
6966
|
if address {
|
|
5876
|
-
return o.lowerFieldAddressExpr(ctx, receiver, ctx.semPkg.source.TypesInfo.TypeOf(expr.X),
|
|
6967
|
+
return o.lowerFieldAddressExpr(ctx, receiver, ctx.semPkg.source.TypesInfo.TypeOf(expr.X), fieldName), diagnostics
|
|
5877
6968
|
}
|
|
5878
|
-
return receiver + "." +
|
|
6969
|
+
return receiver + "." + fieldName, diagnostics
|
|
5879
6970
|
}
|
|
5880
6971
|
|
|
5881
6972
|
typ := derefPointerType(ctx.semPkg.source.TypesInfo.TypeOf(expr.X))
|
|
5882
6973
|
for idx, fieldIndex := range index {
|
|
5883
6974
|
structType := structUnderlyingType(typ)
|
|
5884
6975
|
if structType == nil || fieldIndex < 0 || fieldIndex >= structType.NumFields() {
|
|
6976
|
+
fieldName := tsStructFieldName(expr.Sel.Name, 0)
|
|
5885
6977
|
if address {
|
|
5886
|
-
return receiver + "._fields." +
|
|
6978
|
+
return receiver + "._fields." + fieldName, diagnostics
|
|
5887
6979
|
}
|
|
5888
|
-
return receiver + "." +
|
|
6980
|
+
return receiver + "." + fieldName, diagnostics
|
|
5889
6981
|
}
|
|
5890
6982
|
field := structType.Field(fieldIndex)
|
|
5891
|
-
name := field.Name()
|
|
6983
|
+
name := tsStructFieldName(field.Name(), fieldIndex)
|
|
5892
6984
|
if idx == len(index)-1 {
|
|
5893
6985
|
if address {
|
|
5894
6986
|
return o.lowerFieldAddressExpr(ctx, receiver, typ, name), diagnostics
|
|
@@ -5906,9 +6998,9 @@ func (o *LoweringOwner) lowerFieldSelectionExpr(
|
|
|
5906
6998
|
}
|
|
5907
6999
|
|
|
5908
7000
|
if address {
|
|
5909
|
-
return o.lowerFieldAddressExpr(ctx, receiver, typ, expr.Sel.Name), diagnostics
|
|
7001
|
+
return o.lowerFieldAddressExpr(ctx, receiver, typ, tsStructFieldName(expr.Sel.Name, 0)), diagnostics
|
|
5910
7002
|
}
|
|
5911
|
-
return receiver + "." + expr.Sel.Name, diagnostics
|
|
7003
|
+
return receiver + "." + tsStructFieldName(expr.Sel.Name, 0), diagnostics
|
|
5912
7004
|
}
|
|
5913
7005
|
|
|
5914
7006
|
func (o *LoweringOwner) lowerFieldAddressExpr(ctx lowerFileContext, receiver string, typ types.Type, fieldName string) string {
|
|
@@ -5980,9 +7072,11 @@ func (o *LoweringOwner) lowerFieldReceiverExpr(ctx lowerFileContext, expr ast.Ex
|
|
|
5980
7072
|
return o.lowerPointerValueExpr(ctx, expr)
|
|
5981
7073
|
}
|
|
5982
7074
|
value, diagnostics := o.lowerExpr(ctx, expr)
|
|
7075
|
+
value = parenthesizeAwaitedExpr(value)
|
|
5983
7076
|
if obj := objectForValueExpr(ctx, expr); obj != nil &&
|
|
5984
|
-
ctx
|
|
7077
|
+
objectNeedsVarRef(ctx, obj) &&
|
|
5985
7078
|
isStructValueType(obj.Type()) &&
|
|
7079
|
+
!packageVarSelectorNeedsPointerValue(ctx, expr) &&
|
|
5986
7080
|
fieldReceiverNeedsVarRefValue(ctx, expr, obj) {
|
|
5987
7081
|
return value + ".value", diagnostics
|
|
5988
7082
|
}
|
|
@@ -5993,7 +7087,16 @@ func fieldReceiverNeedsVarRefValue(ctx lowerFileContext, expr ast.Expr, obj type
|
|
|
5993
7087
|
if _, ok := expr.(*ast.Ident); !ok {
|
|
5994
7088
|
return true
|
|
5995
7089
|
}
|
|
5996
|
-
|
|
7090
|
+
if ctx.identAliases[obj] != "" {
|
|
7091
|
+
return !ctx.identAliasRefs[obj]
|
|
7092
|
+
}
|
|
7093
|
+
if ctx.localAliases[obj] != "" {
|
|
7094
|
+
if varObj, ok := obj.(*types.Var); ok && packageVarReadNeedsPointerValue(varObj.Type()) {
|
|
7095
|
+
return false
|
|
7096
|
+
}
|
|
7097
|
+
return !ctx.lazyPackageVars[obj]
|
|
7098
|
+
}
|
|
7099
|
+
return false
|
|
5997
7100
|
}
|
|
5998
7101
|
|
|
5999
7102
|
func (o *LoweringOwner) lowerMethodReceiverExpr(
|
|
@@ -6016,14 +7119,24 @@ func (o *LoweringOwner) lowerMethodReceiverExpr(
|
|
|
6016
7119
|
receiver, diagnostics = o.lowerPointerValueExpr(ctx, expr)
|
|
6017
7120
|
} else {
|
|
6018
7121
|
receiver, diagnostics = o.lowerExpr(ctx, expr)
|
|
7122
|
+
receiver = parenthesizeAwaitedExpr(receiver)
|
|
6019
7123
|
}
|
|
6020
7124
|
receiverType := ctx.semPkg.source.TypesInfo.TypeOf(expr)
|
|
7125
|
+
if !receiverPointer {
|
|
7126
|
+
if obj := objectForValueExpr(ctx, expr); obj != nil &&
|
|
7127
|
+
objectNeedsVarRef(ctx, obj) &&
|
|
7128
|
+
isStructValueType(obj.Type()) &&
|
|
7129
|
+
!packageVarSelectorNeedsPointerValue(ctx, expr) &&
|
|
7130
|
+
fieldReceiverNeedsVarRefValue(ctx, expr, obj) {
|
|
7131
|
+
receiver += ".value"
|
|
7132
|
+
}
|
|
7133
|
+
}
|
|
6021
7134
|
if index := selection.Index(); len(index) > 1 && !o.receiverUsesOverridePackage(receiverType) {
|
|
6022
7135
|
receiver, receiverType = o.lowerPromotedMethodReceiver(ctx, receiver, receiverType, index[:len(index)-1])
|
|
6023
7136
|
}
|
|
6024
7137
|
if receiverPointer {
|
|
6025
7138
|
if obj := objectForValueExpr(ctx, expr); obj != nil &&
|
|
6026
|
-
ctx
|
|
7139
|
+
objectNeedsVarRef(ctx, obj) &&
|
|
6027
7140
|
isStructValueType(obj.Type()) &&
|
|
6028
7141
|
fieldReceiverNeedsVarRefValue(ctx, expr, obj) {
|
|
6029
7142
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue) +
|
|
@@ -6074,16 +7187,38 @@ func (o *LoweringOwner) lowerPromotedMethodReceiver(
|
|
|
6074
7187
|
return receiver, typ
|
|
6075
7188
|
}
|
|
6076
7189
|
|
|
7190
|
+
func promotedMethodReceiverType(typ types.Type, index []int) types.Type {
|
|
7191
|
+
typ = derefPointerType(typ)
|
|
7192
|
+
for _, fieldIndex := range index {
|
|
7193
|
+
structType := structUnderlyingType(typ)
|
|
7194
|
+
if structType == nil || fieldIndex < 0 || fieldIndex >= structType.NumFields() {
|
|
7195
|
+
return typ
|
|
7196
|
+
}
|
|
7197
|
+
typ = structType.Field(fieldIndex).Type()
|
|
7198
|
+
if pointer, ok := types.Unalias(typ).Underlying().(*types.Pointer); ok {
|
|
7199
|
+
typ = pointer.Elem()
|
|
7200
|
+
}
|
|
7201
|
+
}
|
|
7202
|
+
return typ
|
|
7203
|
+
}
|
|
7204
|
+
|
|
6077
7205
|
func (o *LoweringOwner) lowerAssignmentTarget(
|
|
6078
7206
|
ctx lowerFileContext,
|
|
6079
7207
|
expr ast.Expr,
|
|
6080
7208
|
declare bool,
|
|
6081
7209
|
) (string, []Diagnostic) {
|
|
6082
|
-
switch typed := expr.(type) {
|
|
7210
|
+
switch typed := unwrapParenExpr(expr).(type) {
|
|
6083
7211
|
case *ast.Ident:
|
|
6084
7212
|
if declare {
|
|
6085
7213
|
return o.lowerIdent(ctx, typed, true), nil
|
|
6086
7214
|
}
|
|
7215
|
+
if obj := objectForIdent(ctx, typed); obj != nil && ctx.lazyPackageVars[obj] {
|
|
7216
|
+
target := o.lowerIdent(ctx, typed, true)
|
|
7217
|
+
if ctx.model.needsVarRef[obj] {
|
|
7218
|
+
target += ".value"
|
|
7219
|
+
}
|
|
7220
|
+
return target, nil
|
|
7221
|
+
}
|
|
6087
7222
|
return o.lowerIdent(ctx, typed, false), nil
|
|
6088
7223
|
case *ast.StarExpr:
|
|
6089
7224
|
return o.lowerPointerValueExpr(ctx, typed.X)
|
|
@@ -6093,7 +7228,10 @@ func (o *LoweringOwner) lowerAssignmentTarget(
|
|
|
6093
7228
|
}
|
|
6094
7229
|
|
|
6095
7230
|
func (o *LoweringOwner) lowerAddressExpr(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
6096
|
-
|
|
7231
|
+
if value, ok := o.lowerPackageVarAddressExpr(ctx, expr); ok {
|
|
7232
|
+
return value, nil
|
|
7233
|
+
}
|
|
7234
|
+
switch typed := unwrapParenExpr(expr).(type) {
|
|
6097
7235
|
case *ast.Ident:
|
|
6098
7236
|
return o.lowerIdent(ctx, typed, true), nil
|
|
6099
7237
|
case *ast.CompositeLit:
|
|
@@ -6115,6 +7253,55 @@ func (o *LoweringOwner) lowerAddressExpr(ctx lowerFileContext, expr ast.Expr) (s
|
|
|
6115
7253
|
}
|
|
6116
7254
|
}
|
|
6117
7255
|
|
|
7256
|
+
func (o *LoweringOwner) lowerPackageVarAddressExpr(ctx lowerFileContext, expr ast.Expr) (string, bool) {
|
|
7257
|
+
switch typed := unwrapParenExpr(expr).(type) {
|
|
7258
|
+
case *ast.Ident:
|
|
7259
|
+
obj, _ := objectForIdent(ctx, typed).(*types.Var)
|
|
7260
|
+
if obj == nil || !objectNeedsVarRef(ctx, obj) {
|
|
7261
|
+
return "", false
|
|
7262
|
+
}
|
|
7263
|
+
return o.lowerIdent(ctx, typed, true), true
|
|
7264
|
+
case *ast.SelectorExpr:
|
|
7265
|
+
if selection := ctx.semPkg.source.TypesInfo.Selections[typed]; selection != nil {
|
|
7266
|
+
return "", false
|
|
7267
|
+
}
|
|
7268
|
+
ident, ok := unwrapParenExpr(typed.X).(*ast.Ident)
|
|
7269
|
+
if !ok {
|
|
7270
|
+
return "", false
|
|
7271
|
+
}
|
|
7272
|
+
pkgName, _ := objectForIdent(ctx, ident).(*types.PkgName)
|
|
7273
|
+
if pkgName == nil {
|
|
7274
|
+
return "", false
|
|
7275
|
+
}
|
|
7276
|
+
alias := importAliasForPkgName(ctx, pkgName)
|
|
7277
|
+
if alias == "" {
|
|
7278
|
+
return "", false
|
|
7279
|
+
}
|
|
7280
|
+
obj, _ := ctx.semPkg.source.TypesInfo.Uses[typed.Sel].(*types.Var)
|
|
7281
|
+
if obj == nil || !objectNeedsVarRef(ctx, obj) {
|
|
7282
|
+
return "", false
|
|
7283
|
+
}
|
|
7284
|
+
return alias + "." + typed.Sel.Name, true
|
|
7285
|
+
default:
|
|
7286
|
+
return "", false
|
|
7287
|
+
}
|
|
7288
|
+
}
|
|
7289
|
+
|
|
7290
|
+
func importAliasForPkgName(ctx lowerFileContext, pkgName *types.PkgName) string {
|
|
7291
|
+
if pkgName == nil {
|
|
7292
|
+
return ""
|
|
7293
|
+
}
|
|
7294
|
+
if alias := ctx.importObjects[pkgName]; alias != "" {
|
|
7295
|
+
return alias
|
|
7296
|
+
}
|
|
7297
|
+
if imported := pkgName.Imported(); imported != nil {
|
|
7298
|
+
if alias := ctx.importPaths[imported.Path()]; alias != "" {
|
|
7299
|
+
return alias
|
|
7300
|
+
}
|
|
7301
|
+
}
|
|
7302
|
+
return ctx.importNames[pkgName.Name()]
|
|
7303
|
+
}
|
|
7304
|
+
|
|
6118
7305
|
func (o *LoweringOwner) lowerIndexAddressExpr(ctx lowerFileContext, expr *ast.IndexExpr) (string, []Diagnostic) {
|
|
6119
7306
|
target, targetDiagnostics := o.lowerExpr(ctx, expr.X)
|
|
6120
7307
|
index, indexDiagnostics := o.lowerExpr(ctx, expr.Index)
|
|
@@ -6160,57 +7347,251 @@ func (o *LoweringOwner) lowerIndexAddressIntegerExpr(
|
|
|
6160
7347
|
if !ok || address.Op != token.AND {
|
|
6161
7348
|
return "", nil, false
|
|
6162
7349
|
}
|
|
6163
|
-
indexExpr, ok := unwrapParenExpr(address.X).(*ast.IndexExpr)
|
|
7350
|
+
indexExpr, ok := unwrapParenExpr(address.X).(*ast.IndexExpr)
|
|
7351
|
+
if !ok {
|
|
7352
|
+
return "", nil, false
|
|
7353
|
+
}
|
|
7354
|
+
target, targetDiagnostics := o.lowerExpr(ctx, indexExpr.X)
|
|
7355
|
+
index, indexDiagnostics := o.lowerExpr(ctx, indexExpr.Index)
|
|
7356
|
+
diagnostics := append(targetDiagnostics, indexDiagnostics...)
|
|
7357
|
+
targetType := ctx.semPkg.source.TypesInfo.TypeOf(indexExpr.X)
|
|
7358
|
+
if isStringType(targetType) || isMapType(targetType) {
|
|
7359
|
+
return "", diagnostics, false
|
|
7360
|
+
}
|
|
7361
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperIndexAddress) +
|
|
7362
|
+
"(" + o.lowerIndexTarget(ctx, target, targetType) + ", " + index + ")", diagnostics, true
|
|
7363
|
+
}
|
|
7364
|
+
|
|
7365
|
+
func (o *LoweringOwner) lowerPointerValueExpr(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
7366
|
+
if value, diagnostics, ok := o.lowerUnsafeStringPointerValue(ctx, expr); ok {
|
|
7367
|
+
return value, diagnostics
|
|
7368
|
+
}
|
|
7369
|
+
if value, diagnostics, ok := o.lowerUnsafeStringByteSlicePointerValue(ctx, expr); ok {
|
|
7370
|
+
return value, diagnostics
|
|
7371
|
+
}
|
|
7372
|
+
base, diagnostics := o.lowerExpr(ctx, expr)
|
|
7373
|
+
typeArg := ""
|
|
7374
|
+
if pointer, ok := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(expr)).Underlying().(*types.Pointer); ok {
|
|
7375
|
+
typeArg = "<" + o.tsTypeFor(ctx, pointer.Elem()) + ">"
|
|
7376
|
+
}
|
|
7377
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue) + typeArg + "(" + base + ")", diagnostics
|
|
7378
|
+
}
|
|
7379
|
+
|
|
7380
|
+
func (o *LoweringOwner) lowerUnsafeStringPointerValue(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic, bool) {
|
|
7381
|
+
call, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
7382
|
+
if !ok || len(call.Args) != 1 {
|
|
7383
|
+
return "", nil, false
|
|
7384
|
+
}
|
|
7385
|
+
targetType := typeFromExpr(ctx, call.Fun)
|
|
7386
|
+
if targetType == nil {
|
|
7387
|
+
return "", nil, false
|
|
7388
|
+
}
|
|
7389
|
+
targetPointer, _ := types.Unalias(targetType).Underlying().(*types.Pointer)
|
|
7390
|
+
if targetPointer == nil || !isStringType(targetPointer.Elem()) {
|
|
7391
|
+
return "", nil, false
|
|
7392
|
+
}
|
|
7393
|
+
unsafeCall, ok := unwrapParenExpr(call.Args[0]).(*ast.CallExpr)
|
|
7394
|
+
unsafeTargetType := typeFromExpr(ctx, unsafeCall.Fun)
|
|
7395
|
+
if !ok || len(unsafeCall.Args) != 1 || unsafeTargetType == nil || !isUnsafePointerType(unsafeTargetType) {
|
|
7396
|
+
return "", nil, false
|
|
7397
|
+
}
|
|
7398
|
+
address, ok := unwrapParenExpr(unsafeCall.Args[0]).(*ast.UnaryExpr)
|
|
7399
|
+
if !ok || address.Op != token.AND || !isByteSliceType(ctx.semPkg.source.TypesInfo.TypeOf(address.X)) {
|
|
7400
|
+
return "", nil, false
|
|
7401
|
+
}
|
|
7402
|
+
value, diagnostics := o.lowerExpr(ctx, address.X)
|
|
7403
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperBytesToString) + "(" + value + ")", diagnostics, true
|
|
7404
|
+
}
|
|
7405
|
+
|
|
7406
|
+
func (o *LoweringOwner) lowerUnsafeStringByteSlicePointerValue(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic, bool) {
|
|
7407
|
+
call, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
7408
|
+
if !ok || len(call.Args) != 1 {
|
|
7409
|
+
return "", nil, false
|
|
7410
|
+
}
|
|
7411
|
+
targetType := typeFromExpr(ctx, call.Fun)
|
|
7412
|
+
if targetType == nil {
|
|
7413
|
+
return "", nil, false
|
|
7414
|
+
}
|
|
7415
|
+
targetPointer, _ := types.Unalias(targetType).Underlying().(*types.Pointer)
|
|
7416
|
+
if targetPointer == nil || !isByteSliceType(targetPointer.Elem()) {
|
|
7417
|
+
return "", nil, false
|
|
7418
|
+
}
|
|
7419
|
+
unsafeCall, ok := unwrapParenExpr(call.Args[0]).(*ast.CallExpr)
|
|
7420
|
+
unsafeTargetType := typeFromExpr(ctx, unsafeCall.Fun)
|
|
7421
|
+
if !ok || len(unsafeCall.Args) != 1 || unsafeTargetType == nil || !isUnsafePointerType(unsafeTargetType) {
|
|
7422
|
+
return "", nil, false
|
|
7423
|
+
}
|
|
7424
|
+
address, ok := unwrapParenExpr(unsafeCall.Args[0]).(*ast.UnaryExpr)
|
|
7425
|
+
if !ok || address.Op != token.AND {
|
|
7426
|
+
return "", nil, false
|
|
7427
|
+
}
|
|
7428
|
+
source, ok := localStringSliceHeaderSource(ctx, address.X)
|
|
7429
|
+
if !ok {
|
|
7430
|
+
return "", nil, false
|
|
7431
|
+
}
|
|
7432
|
+
value, diagnostics := o.lowerExpr(ctx, source)
|
|
7433
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperStringToBytes) + "(" + value + ")", diagnostics, true
|
|
7434
|
+
}
|
|
7435
|
+
|
|
7436
|
+
func (o *LoweringOwner) lowerReflectHeaderPointerConversion(
|
|
7437
|
+
ctx lowerFileContext,
|
|
7438
|
+
targetType types.Type,
|
|
7439
|
+
expr ast.Expr,
|
|
7440
|
+
) (string, []Diagnostic, bool) {
|
|
7441
|
+
targetPointer, _ := types.Unalias(targetType).Underlying().(*types.Pointer)
|
|
7442
|
+
if targetPointer == nil {
|
|
7443
|
+
return "", nil, false
|
|
7444
|
+
}
|
|
7445
|
+
header, _ := types.Unalias(targetPointer.Elem()).(*types.Named)
|
|
7446
|
+
if header == nil || header.Obj() == nil || header.Obj().Pkg() == nil || header.Obj().Pkg().Path() != "reflect" {
|
|
7447
|
+
return "", nil, false
|
|
7448
|
+
}
|
|
7449
|
+
unsafeCall, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
7450
|
+
if !ok || len(unsafeCall.Args) != 1 || !isUnsafePointerType(typeFromExpr(ctx, unsafeCall.Fun)) {
|
|
7451
|
+
return "", nil, false
|
|
7452
|
+
}
|
|
7453
|
+
address, ok := unwrapParenExpr(unsafeCall.Args[0]).(*ast.UnaryExpr)
|
|
7454
|
+
if !ok || address.Op != token.AND {
|
|
7455
|
+
return "", nil, false
|
|
7456
|
+
}
|
|
7457
|
+
switch header.Obj().Name() {
|
|
7458
|
+
case "StringHeader":
|
|
7459
|
+
if !isStringType(ctx.semPkg.source.TypesInfo.TypeOf(address.X)) {
|
|
7460
|
+
return "", nil, false
|
|
7461
|
+
}
|
|
7462
|
+
value, diagnostics := o.lowerAddressedValueRef(ctx, address.X)
|
|
7463
|
+
helper := o.runtimeOwner.QualifiedHelper(RuntimeHelperStringHeaderRef) + "(" + value + ")"
|
|
7464
|
+
return "(" + helper + " as unknown as " + o.tsTypeFor(ctx, targetType) + ")", diagnostics, true
|
|
7465
|
+
case "SliceHeader":
|
|
7466
|
+
if !isByteSliceType(ctx.semPkg.source.TypesInfo.TypeOf(address.X)) {
|
|
7467
|
+
return "", nil, false
|
|
7468
|
+
}
|
|
7469
|
+
value, diagnostics := o.lowerAddressedValueRef(ctx, address.X)
|
|
7470
|
+
helper := o.runtimeOwner.QualifiedHelper(RuntimeHelperSliceHeaderRef) + "(" + value + ")"
|
|
7471
|
+
return "(" + helper + " as unknown as " + o.tsTypeFor(ctx, targetType) + ")", diagnostics, true
|
|
7472
|
+
default:
|
|
7473
|
+
return "", nil, false
|
|
7474
|
+
}
|
|
7475
|
+
}
|
|
7476
|
+
|
|
7477
|
+
func (o *LoweringOwner) lowerUnsafeArrayPointerConversion(
|
|
7478
|
+
ctx lowerFileContext,
|
|
7479
|
+
targetType types.Type,
|
|
7480
|
+
expr ast.Expr,
|
|
7481
|
+
) (string, []Diagnostic, bool) {
|
|
7482
|
+
targetPointer, _ := types.Unalias(targetType).Underlying().(*types.Pointer)
|
|
7483
|
+
if targetPointer == nil {
|
|
7484
|
+
return "", nil, false
|
|
7485
|
+
}
|
|
7486
|
+
array, _ := types.Unalias(targetPointer.Elem()).Underlying().(*types.Array)
|
|
7487
|
+
if array == nil {
|
|
7488
|
+
return "", nil, false
|
|
7489
|
+
}
|
|
7490
|
+
unsafeCall, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
7491
|
+
if !ok || len(unsafeCall.Args) != 1 || !isUnsafePointerType(typeFromExpr(ctx, unsafeCall.Fun)) {
|
|
7492
|
+
return "", nil, false
|
|
7493
|
+
}
|
|
7494
|
+
address, ok := unwrapParenExpr(unsafeCall.Args[0]).(*ast.UnaryExpr)
|
|
7495
|
+
if !ok || address.Op != token.AND {
|
|
7496
|
+
return "", nil, false
|
|
7497
|
+
}
|
|
7498
|
+
index, ok := unwrapParenExpr(address.X).(*ast.IndexExpr)
|
|
6164
7499
|
if !ok {
|
|
6165
7500
|
return "", nil, false
|
|
6166
7501
|
}
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
7502
|
+
ref, diagnostics := o.lowerAddressExpr(ctx, index)
|
|
7503
|
+
helper := o.runtimeOwner.QualifiedHelper(RuntimeHelperArrayPointerFromIndexRef) +
|
|
7504
|
+
"<" + o.tsTypeFor(ctx, array.Elem()) + ">(" + ref + ", " + strconv.FormatInt(array.Len(), 10) + ")"
|
|
7505
|
+
return "(" + helper + " as unknown as " + o.tsTypeFor(ctx, targetType) + ")", diagnostics, true
|
|
7506
|
+
}
|
|
7507
|
+
|
|
7508
|
+
func (o *LoweringOwner) lowerAddressedValueRef(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
7509
|
+
if ident, ok := unwrapParenExpr(expr).(*ast.Ident); ok {
|
|
7510
|
+
if obj := objectForIdent(ctx, ident); obj != nil && ctx.model.needsVarRef[obj] {
|
|
7511
|
+
return o.lowerIdent(ctx, ident, true), nil
|
|
7512
|
+
}
|
|
6173
7513
|
}
|
|
6174
|
-
|
|
6175
|
-
|
|
7514
|
+
value, diagnostics := o.lowerExpr(ctx, expr)
|
|
7515
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperVarRef) + "(" + value + ")", diagnostics
|
|
6176
7516
|
}
|
|
6177
7517
|
|
|
6178
|
-
func (
|
|
6179
|
-
|
|
6180
|
-
|
|
7518
|
+
func localStringSliceHeaderSource(ctx lowerFileContext, expr ast.Expr) (ast.Expr, bool) {
|
|
7519
|
+
lit, ok := unwrapParenExpr(expr).(*ast.CompositeLit)
|
|
7520
|
+
if !ok {
|
|
7521
|
+
return nil, false
|
|
6181
7522
|
}
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
typeArg = "<" + o.tsTypeFor(ctx, pointer.Elem()) + ">"
|
|
7523
|
+
structType, ok := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(lit)).Underlying().(*types.Struct)
|
|
7524
|
+
if !ok || structType.NumFields() != 2 {
|
|
7525
|
+
return nil, false
|
|
6186
7526
|
}
|
|
6187
|
-
|
|
7527
|
+
if !isStringType(structType.Field(0).Type()) || !isIntegerType(structType.Field(1).Type()) {
|
|
7528
|
+
return nil, false
|
|
7529
|
+
}
|
|
7530
|
+
var source ast.Expr
|
|
7531
|
+
var capacity ast.Expr
|
|
7532
|
+
for idx, elt := range lit.Elts {
|
|
7533
|
+
fieldIndex := idx
|
|
7534
|
+
valueExpr := elt
|
|
7535
|
+
if keyed, ok := elt.(*ast.KeyValueExpr); ok {
|
|
7536
|
+
valueExpr = keyed.Value
|
|
7537
|
+
ident, ok := keyed.Key.(*ast.Ident)
|
|
7538
|
+
if !ok {
|
|
7539
|
+
return nil, false
|
|
7540
|
+
}
|
|
7541
|
+
fieldIndex = -1
|
|
7542
|
+
for index := range structType.NumFields() {
|
|
7543
|
+
if structType.Field(index).Name() == ident.Name {
|
|
7544
|
+
fieldIndex = index
|
|
7545
|
+
break
|
|
7546
|
+
}
|
|
7547
|
+
}
|
|
7548
|
+
if fieldIndex < 0 {
|
|
7549
|
+
return nil, false
|
|
7550
|
+
}
|
|
7551
|
+
}
|
|
7552
|
+
switch fieldIndex {
|
|
7553
|
+
case 0:
|
|
7554
|
+
source = valueExpr
|
|
7555
|
+
case 1:
|
|
7556
|
+
capacity = valueExpr
|
|
7557
|
+
}
|
|
7558
|
+
}
|
|
7559
|
+
if source == nil || capacity == nil {
|
|
7560
|
+
return nil, false
|
|
7561
|
+
}
|
|
7562
|
+
if !isStringType(ctx.semPkg.source.TypesInfo.TypeOf(source)) ||
|
|
7563
|
+
!isIntegerType(ctx.semPkg.source.TypesInfo.TypeOf(capacity)) {
|
|
7564
|
+
return nil, false
|
|
7565
|
+
}
|
|
7566
|
+
if !isLenCallOfExpr(ctx, capacity, source) {
|
|
7567
|
+
return nil, false
|
|
7568
|
+
}
|
|
7569
|
+
return source, true
|
|
6188
7570
|
}
|
|
6189
7571
|
|
|
6190
|
-
func (
|
|
7572
|
+
func isLenCallOfExpr(ctx lowerFileContext, expr ast.Expr, target ast.Expr) bool {
|
|
6191
7573
|
call, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
6192
7574
|
if !ok || len(call.Args) != 1 {
|
|
6193
|
-
return
|
|
6194
|
-
}
|
|
6195
|
-
targetType := typeFromExpr(ctx, call.Fun)
|
|
6196
|
-
if targetType == nil {
|
|
6197
|
-
return "", nil, false
|
|
7575
|
+
return false
|
|
6198
7576
|
}
|
|
6199
|
-
|
|
6200
|
-
if
|
|
6201
|
-
return
|
|
7577
|
+
ident, ok := unwrapParenExpr(call.Fun).(*ast.Ident)
|
|
7578
|
+
if !ok || ident.Name != "len" {
|
|
7579
|
+
return false
|
|
6202
7580
|
}
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
if !ok || len(unsafeCall.Args) != 1 || unsafeTargetType == nil || !isUnsafePointerType(unsafeTargetType) {
|
|
6206
|
-
return "", nil, false
|
|
7581
|
+
if objectForIdent(ctx, ident) != types.Universe.Lookup("len") {
|
|
7582
|
+
return false
|
|
6207
7583
|
}
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
7584
|
+
return sameLoweredSourceExpr(ctx, call.Args[0], target)
|
|
7585
|
+
}
|
|
7586
|
+
|
|
7587
|
+
func sameLoweredSourceExpr(ctx lowerFileContext, left ast.Expr, right ast.Expr) bool {
|
|
7588
|
+
left = unwrapParenExpr(left)
|
|
7589
|
+
right = unwrapParenExpr(right)
|
|
7590
|
+
if leftIdent, ok := left.(*ast.Ident); ok {
|
|
7591
|
+
rightIdent, ok := right.(*ast.Ident)
|
|
7592
|
+
return ok && objectForIdent(ctx, leftIdent) == objectForIdent(ctx, rightIdent)
|
|
6211
7593
|
}
|
|
6212
|
-
|
|
6213
|
-
return o.runtimeOwner.QualifiedHelper(RuntimeHelperBytesToString) + "(" + value + ")", diagnostics, true
|
|
7594
|
+
return false
|
|
6214
7595
|
}
|
|
6215
7596
|
|
|
6216
7597
|
func (o *LoweringOwner) lowerPointerStorageExpr(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
@@ -6362,6 +7743,13 @@ func (o *LoweringOwner) lowerCompositeLit(
|
|
|
6362
7743
|
lit *ast.CompositeLit,
|
|
6363
7744
|
markStruct bool,
|
|
6364
7745
|
) (string, []Diagnostic) {
|
|
7746
|
+
if len(lit.Elts) == 0 {
|
|
7747
|
+
if typeParam, ok := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(lit)).(*types.TypeParam); ok {
|
|
7748
|
+
if typeParamInScope(ctx, typeParam) {
|
|
7749
|
+
return o.lowerDeclarationZeroValueExpr(ctx, typeParam), nil
|
|
7750
|
+
}
|
|
7751
|
+
}
|
|
7752
|
+
}
|
|
6365
7753
|
named := namedStructType(ctx.semPkg.source.TypesInfo.TypeOf(lit))
|
|
6366
7754
|
if named != nil {
|
|
6367
7755
|
return o.lowerStructCompositeLit(ctx, lit, named, markStruct)
|
|
@@ -6402,6 +7790,7 @@ func (o *LoweringOwner) lowerStructCompositeLit(
|
|
|
6402
7790
|
) (string, []Diagnostic) {
|
|
6403
7791
|
structType, _ := named.Underlying().(*types.Struct)
|
|
6404
7792
|
fields := make([]string, 0, len(lit.Elts))
|
|
7793
|
+
var prelude []string
|
|
6405
7794
|
var diagnostics []Diagnostic
|
|
6406
7795
|
for idx, elt := range lit.Elts {
|
|
6407
7796
|
fieldName := ""
|
|
@@ -6410,9 +7799,13 @@ func (o *LoweringOwner) lowerStructCompositeLit(
|
|
|
6410
7799
|
if keyed, ok := elt.(*ast.KeyValueExpr); ok {
|
|
6411
7800
|
valueExpr = keyed.Value
|
|
6412
7801
|
if ident, ok := keyed.Key.(*ast.Ident); ok {
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
7802
|
+
for index := range structType.NumFields() {
|
|
7803
|
+
field := structType.Field(index)
|
|
7804
|
+
if field.Name() == ident.Name {
|
|
7805
|
+
fieldName = tsStructFieldName(field.Name(), index)
|
|
7806
|
+
fieldType = field.Type()
|
|
7807
|
+
break
|
|
7808
|
+
}
|
|
6416
7809
|
}
|
|
6417
7810
|
}
|
|
6418
7811
|
} else if idx < structType.NumFields() {
|
|
@@ -6427,6 +7820,11 @@ func (o *LoweringOwner) lowerStructCompositeLit(
|
|
|
6427
7820
|
value, valueDiagnostics := o.lowerExpr(ctx, valueExpr)
|
|
6428
7821
|
diagnostics = append(diagnostics, valueDiagnostics...)
|
|
6429
7822
|
value = o.lowerValueForTarget(ctx, valueExpr, fieldType, value)
|
|
7823
|
+
if compositeLiteralFieldNeedsPreEval(ctx, valueExpr) {
|
|
7824
|
+
temp := ctx.tempName("LiteralField")
|
|
7825
|
+
prelude = append(prelude, "const "+temp+" = "+value)
|
|
7826
|
+
value = temp
|
|
7827
|
+
}
|
|
6430
7828
|
fields = append(fields, fieldName+": "+value)
|
|
6431
7829
|
}
|
|
6432
7830
|
|
|
@@ -6437,9 +7835,30 @@ func (o *LoweringOwner) lowerStructCompositeLit(
|
|
|
6437
7835
|
if markStruct {
|
|
6438
7836
|
expr = o.runtimeOwner.QualifiedHelper(RuntimeHelperMarkAsStructValue) + "(" + expr + ")"
|
|
6439
7837
|
}
|
|
7838
|
+
if len(prelude) != 0 {
|
|
7839
|
+
body := strings.Join(prelude, "; ") + "; return " + expr
|
|
7840
|
+
if strings.Contains(body, "await ") {
|
|
7841
|
+
return "(await (async () => { " + body + " })())", diagnostics
|
|
7842
|
+
}
|
|
7843
|
+
return "(() => { " + body + " })()", diagnostics
|
|
7844
|
+
}
|
|
6440
7845
|
return expr, diagnostics
|
|
6441
7846
|
}
|
|
6442
7847
|
|
|
7848
|
+
func compositeLiteralFieldNeedsPreEval(ctx lowerFileContext, expr ast.Expr) bool {
|
|
7849
|
+
switch typed := unwrapParenExpr(expr).(type) {
|
|
7850
|
+
case *ast.CallExpr:
|
|
7851
|
+
if ident, ok := typed.Fun.(*ast.Ident); ok && isBuiltinCallTarget(ctx, ident) {
|
|
7852
|
+
return false
|
|
7853
|
+
}
|
|
7854
|
+
return typeFromExpr(ctx, typed.Fun) == nil
|
|
7855
|
+
case *ast.UnaryExpr:
|
|
7856
|
+
return typed.Op == token.ARROW
|
|
7857
|
+
default:
|
|
7858
|
+
return false
|
|
7859
|
+
}
|
|
7860
|
+
}
|
|
7861
|
+
|
|
6443
7862
|
func (o *LoweringOwner) lowerAnonymousStructCompositeLit(
|
|
6444
7863
|
ctx lowerFileContext,
|
|
6445
7864
|
lit *ast.CompositeLit,
|
|
@@ -6460,10 +7879,10 @@ func (o *LoweringOwner) lowerAnonymousStructCompositeLit(
|
|
|
6460
7879
|
if keyed, ok := elt.(*ast.KeyValueExpr); ok {
|
|
6461
7880
|
valueExpr = keyed.Value
|
|
6462
7881
|
if ident, ok := keyed.Key.(*ast.Ident); ok {
|
|
6463
|
-
fieldName = ident.Name
|
|
6464
7882
|
for index := range structType.NumFields() {
|
|
6465
7883
|
field := structType.Field(index)
|
|
6466
|
-
if field.Name() ==
|
|
7884
|
+
if field.Name() == ident.Name {
|
|
7885
|
+
fieldName = tsStructFieldName(field.Name(), index)
|
|
6467
7886
|
fieldIndex = index
|
|
6468
7887
|
fieldType = field.Type()
|
|
6469
7888
|
break
|
|
@@ -6571,7 +7990,7 @@ func (o *LoweringOwner) lowerSliceCompositeLit(
|
|
|
6571
7990
|
nextIndex = index + 1
|
|
6572
7991
|
}
|
|
6573
7992
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperArrayToSlice) +
|
|
6574
|
-
"<" + o.
|
|
7993
|
+
"<" + o.tsSliceElemTypeFor(ctx, slice.Elem()) + ">([" + strings.Join(values, ", ") + "])", diagnostics
|
|
6575
7994
|
}
|
|
6576
7995
|
|
|
6577
7996
|
func (o *LoweringOwner) lowerMapCompositeLit(
|
|
@@ -6602,7 +8021,7 @@ func (o *LoweringOwner) lowerTypeAssertExpr(ctx lowerFileContext, expr *ast.Type
|
|
|
6602
8021
|
targetType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Type)
|
|
6603
8022
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperMustTypeAssert) +
|
|
6604
8023
|
"<" + o.tsTypeAssertionTypeFor(ctx, targetType) + ">(" +
|
|
6605
|
-
value + ", " + o.
|
|
8024
|
+
value + ", " + o.runtimeTypeAssertInfoExpr(ctx, targetType) + ")", diagnostics
|
|
6606
8025
|
}
|
|
6607
8026
|
|
|
6608
8027
|
func (o *LoweringOwner) lowerTupleExpr(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
@@ -6612,7 +8031,7 @@ func (o *LoweringOwner) lowerTupleExpr(ctx lowerFileContext, expr ast.Expr) (str
|
|
|
6612
8031
|
targetType := ctx.semPkg.source.TypesInfo.TypeOf(typed.Type)
|
|
6613
8032
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperTypeAssertTuple) +
|
|
6614
8033
|
"<" + o.tsTypeAssertionTypeFor(ctx, targetType) + ">(" +
|
|
6615
|
-
value + ", " + o.
|
|
8034
|
+
value + ", " + o.runtimeTypeAssertInfoExpr(ctx, targetType) + ")", diagnostics
|
|
6616
8035
|
case *ast.IndexExpr:
|
|
6617
8036
|
if isMapType(ctx.semPkg.source.TypesInfo.TypeOf(typed.X)) {
|
|
6618
8037
|
target, targetDiagnostics := o.lowerExpr(ctx, typed.X)
|
|
@@ -6644,6 +8063,9 @@ func (o *LoweringOwner) lowerValueForTarget(
|
|
|
6644
8063
|
) string {
|
|
6645
8064
|
sourceType := ctx.semPkg.source.TypesInfo.TypeOf(expr)
|
|
6646
8065
|
if isComplexType(targetType) {
|
|
8066
|
+
if isComplexType(sourceType) {
|
|
8067
|
+
return value
|
|
8068
|
+
}
|
|
6647
8069
|
if isRealNumericConstantExpr(ctx, expr) {
|
|
6648
8070
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperComplex) + "(" + value + ", 0)"
|
|
6649
8071
|
}
|
|
@@ -6697,6 +8119,14 @@ func isRealNumericConstantExpr(ctx lowerFileContext, expr ast.Expr) bool {
|
|
|
6697
8119
|
}
|
|
6698
8120
|
}
|
|
6699
8121
|
|
|
8122
|
+
func lowerPrefixUnaryExpr(op token.Token, value string) string {
|
|
8123
|
+
prefix := op.String()
|
|
8124
|
+
if (op == token.SUB && strings.HasPrefix(value, "-")) || (op == token.ADD && strings.HasPrefix(value, "+")) {
|
|
8125
|
+
return prefix + "(" + value + ")"
|
|
8126
|
+
}
|
|
8127
|
+
return prefix + value
|
|
8128
|
+
}
|
|
8129
|
+
|
|
6700
8130
|
func (o *LoweringOwner) lowerValueForTargetTypes(
|
|
6701
8131
|
ctx lowerFileContext,
|
|
6702
8132
|
targetType types.Type,
|
|
@@ -6704,6 +8134,9 @@ func (o *LoweringOwner) lowerValueForTargetTypes(
|
|
|
6704
8134
|
value string,
|
|
6705
8135
|
cloneStructValue bool,
|
|
6706
8136
|
) string {
|
|
8137
|
+
if targetType == nil || sourceType == nil {
|
|
8138
|
+
return value
|
|
8139
|
+
}
|
|
6707
8140
|
if isFunctionType(targetType) && isUntypedNilType(sourceType) {
|
|
6708
8141
|
return "(" + value + " as " + o.tsTypeFor(ctx, targetType) + ")"
|
|
6709
8142
|
}
|
|
@@ -6734,6 +8167,15 @@ func (o *LoweringOwner) lowerValueForTargetTypes(
|
|
|
6734
8167
|
return o.lowerStructClone(value)
|
|
6735
8168
|
}
|
|
6736
8169
|
if isIntegerType(targetType) && isIntegerType(sourceType) {
|
|
8170
|
+
if isBasicFixedWideIntegerType(targetType) {
|
|
8171
|
+
if bits, ok := unsignedIntegerBits(targetType); ok {
|
|
8172
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint) +
|
|
8173
|
+
"(" + value + ", " + strconv.Itoa(bits) + ")"
|
|
8174
|
+
}
|
|
8175
|
+
if _, ok := signedIntegerBits(targetType); ok {
|
|
8176
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperInt) + "(" + value + ")"
|
|
8177
|
+
}
|
|
8178
|
+
}
|
|
6737
8179
|
if bits, ok := unsignedIntegerBits(targetType); ok && bits < 64 {
|
|
6738
8180
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint) +
|
|
6739
8181
|
"(" + value + ", " + strconv.Itoa(bits) + ")"
|
|
@@ -6751,12 +8193,28 @@ func (o *LoweringOwner) lowerValueForTargetTypes(
|
|
|
6751
8193
|
return value
|
|
6752
8194
|
}
|
|
6753
8195
|
|
|
8196
|
+
func isBasicFixedWideIntegerType(typ types.Type) bool {
|
|
8197
|
+
basic, ok := types.Unalias(typ).(*types.Basic)
|
|
8198
|
+
if !ok {
|
|
8199
|
+
return false
|
|
8200
|
+
}
|
|
8201
|
+
switch basic.Kind() {
|
|
8202
|
+
case types.Int64, types.Uint64, types.Uintptr:
|
|
8203
|
+
return true
|
|
8204
|
+
default:
|
|
8205
|
+
return false
|
|
8206
|
+
}
|
|
8207
|
+
}
|
|
8208
|
+
|
|
6754
8209
|
func (o *LoweringOwner) lowerNamedValueInterfaceWrapper(
|
|
6755
8210
|
ctx lowerFileContext,
|
|
6756
8211
|
targetType types.Type,
|
|
6757
8212
|
sourceType types.Type,
|
|
6758
8213
|
value string,
|
|
6759
8214
|
) string {
|
|
8215
|
+
if targetType == nil || sourceType == nil {
|
|
8216
|
+
return ""
|
|
8217
|
+
}
|
|
6760
8218
|
if !isInterfaceType(targetType) || isInterfaceType(sourceType) {
|
|
6761
8219
|
return ""
|
|
6762
8220
|
}
|
|
@@ -6794,8 +8252,9 @@ func (o *LoweringOwner) lowerPrimitiveErrorWrapper(ctx lowerFileContext, sourceT
|
|
|
6794
8252
|
if fn == nil {
|
|
6795
8253
|
return ""
|
|
6796
8254
|
}
|
|
6797
|
-
return o.runtimeOwner.QualifiedHelper(
|
|
6798
|
-
"(" + value + ", " +
|
|
8255
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperNamedValueInterfaceValue) +
|
|
8256
|
+
"<$.GoError>(" + value + ", " + strconv.Quote(goRuntimeTypeString(sourceType)) +
|
|
8257
|
+
", {\"Error\": " + o.methodFunctionExpr(ctx, named, fn, "Error") + "})"
|
|
6799
8258
|
}
|
|
6800
8259
|
|
|
6801
8260
|
func (o *LoweringOwner) lowerStructClone(value string) string {
|
|
@@ -6812,6 +8271,9 @@ func (o *LoweringOwner) lowerZeroValueExpr(typ types.Type) string {
|
|
|
6812
8271
|
|
|
6813
8272
|
func (o *LoweringOwner) lowerZeroValueExprFor(ctx lowerFileContext, typ types.Type) string {
|
|
6814
8273
|
if named := namedStructType(typ); named != nil && isStructValueType(typ) {
|
|
8274
|
+
if crossPackageUnexportedNamedType(ctx, named) {
|
|
8275
|
+
return "undefined as any"
|
|
8276
|
+
}
|
|
6815
8277
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperMarkAsStructValue) + "(new " + o.namedTypeExpr(ctx, named) + "())"
|
|
6816
8278
|
}
|
|
6817
8279
|
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
@@ -6859,7 +8321,7 @@ func (o *LoweringOwner) lowerDeclarationZeroValueExpr(ctx lowerFileContext, typ
|
|
|
6859
8321
|
}
|
|
6860
8322
|
return value
|
|
6861
8323
|
}
|
|
6862
|
-
if !
|
|
8324
|
+
if !typeParamInScope(ctx, typeParam) {
|
|
6863
8325
|
return zeroValueExpr(typ)
|
|
6864
8326
|
}
|
|
6865
8327
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperGenericZero) +
|
|
@@ -6870,6 +8332,15 @@ func (o *LoweringOwner) runtimeTypeInfoExpr(typ types.Type) string {
|
|
|
6870
8332
|
return o.runtimeTypeInfoExprWithSeen(typ, make(map[types.Type]bool))
|
|
6871
8333
|
}
|
|
6872
8334
|
|
|
8335
|
+
func (o *LoweringOwner) runtimeTypeAssertInfoExpr(ctx lowerFileContext, typ types.Type) string {
|
|
8336
|
+
typeParam, ok := types.Unalias(typ).(*types.TypeParam)
|
|
8337
|
+
if !ok || !typeParamInScope(ctx, typeParam) {
|
|
8338
|
+
return o.runtimeTypeInfoExpr(typ)
|
|
8339
|
+
}
|
|
8340
|
+
return "__typeArgs?.[" + strconv.Quote(typeParam.Obj().Name()) + "]?.type ?? " +
|
|
8341
|
+
o.runtimeTypeInfoExpr(typ)
|
|
8342
|
+
}
|
|
8343
|
+
|
|
6873
8344
|
func (o *LoweringOwner) runtimeTypeInfoExprWithSeen(typ types.Type, seen map[types.Type]bool) string {
|
|
6874
8345
|
typeKind := o.runtimeOwner.QualifiedHelper(RuntimeHelperTypeKind)
|
|
6875
8346
|
if typ == nil {
|
|
@@ -6890,20 +8361,14 @@ func (o *LoweringOwner) runtimeTypeInfoExprWithSeen(typ types.Type, seen map[typ
|
|
|
6890
8361
|
return o.runtimeFunctionTypeInfoWithSeen(named.Underlying().(*types.Signature), runtimeNamedTypeName(named), seen)
|
|
6891
8362
|
}
|
|
6892
8363
|
if named := namedNonStructType(typ); named != nil {
|
|
8364
|
+
if basic, ok := types.Unalias(named.Underlying()).(*types.Basic); ok {
|
|
8365
|
+
return runtimeBasicTypeInfoExpr(typeKind, basic, runtimeNamedTypeName(named))
|
|
8366
|
+
}
|
|
6893
8367
|
return strconv.Quote(runtimeNamedTypeName(named))
|
|
6894
8368
|
}
|
|
6895
8369
|
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
6896
8370
|
case *types.Basic:
|
|
6897
|
-
|
|
6898
|
-
case typed.Info()&types.IsBoolean != 0:
|
|
6899
|
-
return "{ kind: " + typeKind + ".Basic, name: \"bool\" }"
|
|
6900
|
-
case typed.Info()&types.IsString != 0:
|
|
6901
|
-
return "{ kind: " + typeKind + ".Basic, name: \"string\" }"
|
|
6902
|
-
case typed.Info()&types.IsNumeric != 0:
|
|
6903
|
-
return "{ kind: " + typeKind + ".Basic, name: \"" + basicRuntimeName(typed) + "\" }"
|
|
6904
|
-
default:
|
|
6905
|
-
return "{ kind: " + typeKind + ".Basic, name: \"unknown\" }"
|
|
6906
|
-
}
|
|
8371
|
+
return runtimeBasicTypeInfoExpr(typeKind, typed, "")
|
|
6907
8372
|
case *types.Pointer:
|
|
6908
8373
|
return "{ kind: " + typeKind + ".Pointer, elemType: " + o.runtimeTypeInfoExprWithSeen(typed.Elem(), seen) + " }"
|
|
6909
8374
|
case *types.Struct:
|
|
@@ -6926,6 +8391,23 @@ func (o *LoweringOwner) runtimeTypeInfoExprWithSeen(typ types.Type, seen map[typ
|
|
|
6926
8391
|
}
|
|
6927
8392
|
}
|
|
6928
8393
|
|
|
8394
|
+
func runtimeBasicTypeInfoExpr(typeKind string, basic *types.Basic, typeName string) string {
|
|
8395
|
+
name := "unknown"
|
|
8396
|
+
switch {
|
|
8397
|
+
case basic.Info()&types.IsBoolean != 0:
|
|
8398
|
+
name = "bool"
|
|
8399
|
+
case basic.Info()&types.IsString != 0:
|
|
8400
|
+
name = "string"
|
|
8401
|
+
case basic.Info()&types.IsNumeric != 0:
|
|
8402
|
+
name = basicRuntimeName(basic)
|
|
8403
|
+
}
|
|
8404
|
+
parts := []string{"kind: " + typeKind + ".Basic", "name: " + strconv.Quote(name)}
|
|
8405
|
+
if typeName != "" {
|
|
8406
|
+
parts = append(parts, "typeName: "+strconv.Quote(typeName))
|
|
8407
|
+
}
|
|
8408
|
+
return "{ " + strings.Join(parts, ", ") + " }"
|
|
8409
|
+
}
|
|
8410
|
+
|
|
6929
8411
|
func (o *LoweringOwner) shallowRuntimeTypeInfoExpr(typ types.Type) string {
|
|
6930
8412
|
typeKind := o.runtimeOwner.QualifiedHelper(RuntimeHelperTypeKind)
|
|
6931
8413
|
switch types.Unalias(typ).Underlying().(type) {
|
|
@@ -6998,7 +8480,8 @@ func (o *LoweringOwner) runtimeFunctionTypeInfoWithSeen(signature *types.Signatu
|
|
|
6998
8480
|
if signature.Variadic() {
|
|
6999
8481
|
parts = append(parts, "isVariadic: true")
|
|
7000
8482
|
}
|
|
7001
|
-
|
|
8483
|
+
runtimePackage := strings.TrimSuffix(typeKind, ".TypeKind")
|
|
8484
|
+
return "({ " + strings.Join(parts, ", ") + " } as " + runtimePackage + ".FunctionTypeInfo)"
|
|
7002
8485
|
}
|
|
7003
8486
|
|
|
7004
8487
|
func (o *LoweringOwner) runtimeSignatureTypes(tuple *types.Tuple, seen map[types.Type]bool) string {
|
|
@@ -7012,20 +8495,11 @@ func (o *LoweringOwner) runtimeSignatureTypes(tuple *types.Tuple, seen map[types
|
|
|
7012
8495
|
return "[" + strings.Join(types, ", ") + "]"
|
|
7013
8496
|
}
|
|
7014
8497
|
|
|
7015
|
-
func fieldByName(structType *types.Struct, name string) *types.Var {
|
|
7016
|
-
for field := range structType.Fields() {
|
|
7017
|
-
if field.Name() == name {
|
|
7018
|
-
return field
|
|
7019
|
-
}
|
|
7020
|
-
}
|
|
7021
|
-
return nil
|
|
7022
|
-
}
|
|
7023
|
-
|
|
7024
8498
|
func tsStructFieldName(name string, idx int) string {
|
|
7025
8499
|
if name == "_" {
|
|
7026
8500
|
return "_blank" + strconv.Itoa(idx)
|
|
7027
8501
|
}
|
|
7028
|
-
return name
|
|
8502
|
+
return safeIdentifier(name)
|
|
7029
8503
|
}
|
|
7030
8504
|
|
|
7031
8505
|
func shouldCloneStructValue(expr ast.Expr) bool {
|
|
@@ -7076,6 +8550,11 @@ func (o *LoweringOwner) tsSignatureResultFor(ctx lowerFileContext, signature *ty
|
|
|
7076
8550
|
}
|
|
7077
8551
|
|
|
7078
8552
|
func (o *LoweringOwner) tsSignatureResultTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
8553
|
+
if named, ok := types.Unalias(typ).(*types.Named); ok {
|
|
8554
|
+
if _, ok := types.Unalias(named.Underlying()).(*types.Signature); ok {
|
|
8555
|
+
return o.tsTypeFor(ctx, typ)
|
|
8556
|
+
}
|
|
8557
|
+
}
|
|
7079
8558
|
if signature := signatureForType(typ); ctx.functionTypeDepth == 0 && signature != nil {
|
|
7080
8559
|
return o.tsAsyncCompatibleFunctionResultTypeFor(ctx, signature)
|
|
7081
8560
|
}
|
|
@@ -7139,6 +8618,13 @@ func asyncCompatibleResultType(result string) string {
|
|
|
7139
8618
|
return result + " | " + tsPromiseType(result)
|
|
7140
8619
|
}
|
|
7141
8620
|
|
|
8621
|
+
func asyncCompatibleMethodResultType(result string, async bool) string {
|
|
8622
|
+
if !async {
|
|
8623
|
+
return result
|
|
8624
|
+
}
|
|
8625
|
+
return asyncCompatibleResultType(result)
|
|
8626
|
+
}
|
|
8627
|
+
|
|
7142
8628
|
func tsPromiseType(result string) string {
|
|
7143
8629
|
return "globalThis.Promise<" + result + ">"
|
|
7144
8630
|
}
|
|
@@ -7203,10 +8689,16 @@ func (o *LoweringOwner) tsTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
|
7203
8689
|
if crossPackageUnexportedNamedType(ctx, named) {
|
|
7204
8690
|
return "any"
|
|
7205
8691
|
}
|
|
8692
|
+
if !ctx.canReferenceNamedType(named) {
|
|
8693
|
+
return "any"
|
|
8694
|
+
}
|
|
7206
8695
|
name := o.namedTypeExpr(ctx, named)
|
|
7207
8696
|
if _, ok := named.Underlying().(*types.Interface); ok {
|
|
7208
8697
|
return name + " | null"
|
|
7209
8698
|
}
|
|
8699
|
+
if _, ok := types.Unalias(named.Underlying()).(*types.Signature); ok {
|
|
8700
|
+
return name + " | null"
|
|
8701
|
+
}
|
|
7210
8702
|
return name
|
|
7211
8703
|
}
|
|
7212
8704
|
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
@@ -7233,7 +8725,7 @@ func (o *LoweringOwner) tsTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
|
7233
8725
|
}
|
|
7234
8726
|
return tsArrayType(o.tsTypeFor(ctx, typed.Elem()))
|
|
7235
8727
|
case *types.Slice:
|
|
7236
|
-
return "$.Slice<" + o.
|
|
8728
|
+
return "$.Slice<" + o.tsSliceElemTypeFor(ctx, typed.Elem()) + ">"
|
|
7237
8729
|
case *types.Map:
|
|
7238
8730
|
return "Map<" + o.tsTypeFor(ctx, typed.Key()) + ", " + o.tsTypeFor(ctx, typed.Elem()) + "> | null"
|
|
7239
8731
|
case *types.Chan:
|
|
@@ -7251,12 +8743,18 @@ func (o *LoweringOwner) tsTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
|
7251
8743
|
if crossPackageUnexportedNamedType(ctx, named) {
|
|
7252
8744
|
return "any"
|
|
7253
8745
|
}
|
|
8746
|
+
if !ctx.canReferenceNamedType(named) {
|
|
8747
|
+
return "any"
|
|
8748
|
+
}
|
|
7254
8749
|
return "$.VarRef<" + o.namedTypeExpr(ctx, named) + "> | null"
|
|
7255
8750
|
}
|
|
7256
8751
|
if named := namedStructType(typed.Elem()); named != nil {
|
|
7257
8752
|
if crossPackageUnexportedNamedType(ctx, named) {
|
|
7258
8753
|
return "any"
|
|
7259
8754
|
}
|
|
8755
|
+
if !ctx.canReferenceNamedType(named) {
|
|
8756
|
+
return "any"
|
|
8757
|
+
}
|
|
7260
8758
|
name := o.namedTypeExpr(ctx, named)
|
|
7261
8759
|
return name + " | $.VarRef<" + name + "> | null"
|
|
7262
8760
|
}
|
|
@@ -7272,6 +8770,19 @@ func (o *LoweringOwner) tsTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
|
7272
8770
|
}
|
|
7273
8771
|
}
|
|
7274
8772
|
|
|
8773
|
+
func (o *LoweringOwner) tsSliceElemTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
8774
|
+
if typeParam, ok := types.Unalias(typ).(*types.TypeParam); ok && staticTypeParamInScope(ctx, typeParam) {
|
|
8775
|
+
return safeIdentifier(typeParam.Obj().Name())
|
|
8776
|
+
}
|
|
8777
|
+
if pointer, ok := types.Unalias(typ).(*types.Pointer); ok {
|
|
8778
|
+
if typeParam, ok := types.Unalias(pointer.Elem()).(*types.TypeParam); ok && staticTypeParamInScope(ctx, typeParam) {
|
|
8779
|
+
name := safeIdentifier(typeParam.Obj().Name())
|
|
8780
|
+
return name + " | $.VarRef<" + name + "> | null"
|
|
8781
|
+
}
|
|
8782
|
+
}
|
|
8783
|
+
return o.tsTypeFor(ctx, typ)
|
|
8784
|
+
}
|
|
8785
|
+
|
|
7275
8786
|
func (o *LoweringOwner) tsNonNilTypeFor(ctx lowerFileContext, typ types.Type) string {
|
|
7276
8787
|
if isBuiltinErrorType(typ) {
|
|
7277
8788
|
return "Exclude<$.GoError, null>"
|
|
@@ -7288,6 +8799,9 @@ func (o *LoweringOwner) aliasTypeExpr(ctx lowerFileContext, alias *types.Alias)
|
|
|
7288
8799
|
if alias == nil || alias.Obj() == nil {
|
|
7289
8800
|
return "unknown"
|
|
7290
8801
|
}
|
|
8802
|
+
if !ctx.canReferenceObjectPackage(alias.Obj()) {
|
|
8803
|
+
return "any"
|
|
8804
|
+
}
|
|
7291
8805
|
if alias.Obj().Pkg() == nil {
|
|
7292
8806
|
return o.tsTypeFor(ctx, alias.Rhs())
|
|
7293
8807
|
}
|
|
@@ -7397,6 +8911,14 @@ func namedStructType(typ types.Type) *types.Named {
|
|
|
7397
8911
|
return named
|
|
7398
8912
|
}
|
|
7399
8913
|
|
|
8914
|
+
func pointerToNamedStructType(typ types.Type) *types.Named {
|
|
8915
|
+
pointer, ok := types.Unalias(typ).Underlying().(*types.Pointer)
|
|
8916
|
+
if !ok {
|
|
8917
|
+
return nil
|
|
8918
|
+
}
|
|
8919
|
+
return namedStructType(pointer.Elem())
|
|
8920
|
+
}
|
|
8921
|
+
|
|
7400
8922
|
func namedNonStructType(typ types.Type) *types.Named {
|
|
7401
8923
|
named, _ := types.Unalias(typ).(*types.Named)
|
|
7402
8924
|
if named == nil {
|
|
@@ -7458,6 +8980,94 @@ func signatureHasTypeParam(signature *types.Signature, target *types.TypeParam)
|
|
|
7458
8980
|
return false
|
|
7459
8981
|
}
|
|
7460
8982
|
|
|
8983
|
+
func typeParamInScope(ctx lowerFileContext, target *types.TypeParam) bool {
|
|
8984
|
+
if target == nil {
|
|
8985
|
+
return false
|
|
8986
|
+
}
|
|
8987
|
+
if signatureHasTypeParam(ctx.signature, target) {
|
|
8988
|
+
return true
|
|
8989
|
+
}
|
|
8990
|
+
return ctx.typeParams[target.Obj().Name()]
|
|
8991
|
+
}
|
|
8992
|
+
|
|
8993
|
+
func staticTypeParamInScope(ctx lowerFileContext, target *types.TypeParam) bool {
|
|
8994
|
+
if target == nil || !typeParamInScope(ctx, target) {
|
|
8995
|
+
return false
|
|
8996
|
+
}
|
|
8997
|
+
return ctx.staticTypeParams[target.Obj().Name()]
|
|
8998
|
+
}
|
|
8999
|
+
|
|
9000
|
+
func typeParamConstraintIsAny(typeParam *types.TypeParam) bool {
|
|
9001
|
+
if typeParam == nil {
|
|
9002
|
+
return false
|
|
9003
|
+
}
|
|
9004
|
+
iface, ok := typeParam.Constraint().Underlying().(*types.Interface)
|
|
9005
|
+
if !ok {
|
|
9006
|
+
return false
|
|
9007
|
+
}
|
|
9008
|
+
return iface.NumMethods() == 0 && iface.NumEmbeddeds() == 0
|
|
9009
|
+
}
|
|
9010
|
+
|
|
9011
|
+
func signatureTypeParamNames(signature *types.Signature) []string {
|
|
9012
|
+
if signature == nil || signature.TypeParams() == nil {
|
|
9013
|
+
return nil
|
|
9014
|
+
}
|
|
9015
|
+
typeParams := signature.TypeParams()
|
|
9016
|
+
names := make([]string, 0, typeParams.Len())
|
|
9017
|
+
for typeParam := range typeParams.TypeParams() {
|
|
9018
|
+
if !signatureUsesTypeParamAsSliceElem(signature, typeParam) {
|
|
9019
|
+
continue
|
|
9020
|
+
}
|
|
9021
|
+
names = append(names, safeIdentifier(typeParam.Obj().Name()))
|
|
9022
|
+
}
|
|
9023
|
+
return names
|
|
9024
|
+
}
|
|
9025
|
+
|
|
9026
|
+
func signatureUsesTypeParamAsSliceElem(signature *types.Signature, target *types.TypeParam) bool {
|
|
9027
|
+
if signature == nil || target == nil {
|
|
9028
|
+
return false
|
|
9029
|
+
}
|
|
9030
|
+
return tupleUsesTypeParamAsSliceElem(signature.Params(), target) ||
|
|
9031
|
+
tupleUsesTypeParamAsSliceElem(signature.Results(), target)
|
|
9032
|
+
}
|
|
9033
|
+
|
|
9034
|
+
func tupleUsesTypeParamAsSliceElem(tuple *types.Tuple, target *types.TypeParam) bool {
|
|
9035
|
+
if tuple == nil {
|
|
9036
|
+
return false
|
|
9037
|
+
}
|
|
9038
|
+
for variable := range tuple.Variables() {
|
|
9039
|
+
if typeUsesTypeParamAsSliceElem(variable.Type(), target) {
|
|
9040
|
+
return true
|
|
9041
|
+
}
|
|
9042
|
+
}
|
|
9043
|
+
return false
|
|
9044
|
+
}
|
|
9045
|
+
|
|
9046
|
+
func typeUsesTypeParamAsSliceElem(typ types.Type, target *types.TypeParam) bool {
|
|
9047
|
+
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
9048
|
+
case *types.Slice:
|
|
9049
|
+
if typeParam, ok := types.Unalias(typed.Elem()).(*types.TypeParam); ok &&
|
|
9050
|
+
(typeParam == target || typeParam.Obj() == target.Obj()) {
|
|
9051
|
+
return true
|
|
9052
|
+
}
|
|
9053
|
+
return typeUsesTypeParamAsSliceElem(typed.Elem(), target)
|
|
9054
|
+
case *types.Array:
|
|
9055
|
+
return typeUsesTypeParamAsSliceElem(typed.Elem(), target)
|
|
9056
|
+
case *types.Pointer:
|
|
9057
|
+
return typeUsesTypeParamAsSliceElem(typed.Elem(), target)
|
|
9058
|
+
case *types.Map:
|
|
9059
|
+
return typeUsesTypeParamAsSliceElem(typed.Key(), target) ||
|
|
9060
|
+
typeUsesTypeParamAsSliceElem(typed.Elem(), target)
|
|
9061
|
+
case *types.Chan:
|
|
9062
|
+
return typeUsesTypeParamAsSliceElem(typed.Elem(), target)
|
|
9063
|
+
case *types.Signature:
|
|
9064
|
+
return tupleUsesTypeParamAsSliceElem(typed.Params(), target) ||
|
|
9065
|
+
tupleUsesTypeParamAsSliceElem(typed.Results(), target)
|
|
9066
|
+
default:
|
|
9067
|
+
return false
|
|
9068
|
+
}
|
|
9069
|
+
}
|
|
9070
|
+
|
|
7461
9071
|
func sameNamedTypeOrigin(a *types.Named, b *types.Named) bool {
|
|
7462
9072
|
if a == nil || b == nil {
|
|
7463
9073
|
return false
|
|
@@ -7585,6 +9195,11 @@ func isIntegerType(typ types.Type) bool {
|
|
|
7585
9195
|
return ok && basic.Info()&types.IsInteger != 0
|
|
7586
9196
|
}
|
|
7587
9197
|
|
|
9198
|
+
func isFloatType(typ types.Type) bool {
|
|
9199
|
+
basic, ok := types.Unalias(typ).Underlying().(*types.Basic)
|
|
9200
|
+
return ok && basic.Info()&types.IsFloat != 0
|
|
9201
|
+
}
|
|
9202
|
+
|
|
7588
9203
|
func unsignedIntegerBits(typ types.Type) (int, bool) {
|
|
7589
9204
|
basic, ok := types.Unalias(typ).Underlying().(*types.Basic)
|
|
7590
9205
|
if !ok || basic.Info()&types.IsUnsigned == 0 {
|
|
@@ -7632,6 +9247,9 @@ func isWideIntegerType(typ types.Type) bool {
|
|
|
7632
9247
|
}
|
|
7633
9248
|
|
|
7634
9249
|
func isFixedWideIntegerType(typ types.Type) bool {
|
|
9250
|
+
if typ == nil {
|
|
9251
|
+
return false
|
|
9252
|
+
}
|
|
7635
9253
|
basic, ok := types.Unalias(typ).Underlying().(*types.Basic)
|
|
7636
9254
|
if !ok {
|
|
7637
9255
|
return false
|
|
@@ -7644,6 +9262,14 @@ func isFixedWideIntegerType(typ types.Type) bool {
|
|
|
7644
9262
|
}
|
|
7645
9263
|
}
|
|
7646
9264
|
|
|
9265
|
+
func isFixedSignedWideIntegerType(typ types.Type) bool {
|
|
9266
|
+
if typ == nil {
|
|
9267
|
+
return false
|
|
9268
|
+
}
|
|
9269
|
+
basic, ok := types.Unalias(typ).Underlying().(*types.Basic)
|
|
9270
|
+
return ok && basic.Kind() == types.Int64
|
|
9271
|
+
}
|
|
9272
|
+
|
|
7647
9273
|
func isRuneSliceType(typ types.Type) bool {
|
|
7648
9274
|
slice, ok := types.Unalias(typ).Underlying().(*types.Slice)
|
|
7649
9275
|
return ok && isRuneType(slice.Elem())
|
|
@@ -7672,6 +9298,8 @@ func sliceTypeHint(typ types.Type) string {
|
|
|
7672
9298
|
return "string"
|
|
7673
9299
|
case isNumericType(typ):
|
|
7674
9300
|
return "number"
|
|
9301
|
+
case isBoolType(typ):
|
|
9302
|
+
return "boolean"
|
|
7675
9303
|
default:
|
|
7676
9304
|
return ""
|
|
7677
9305
|
}
|
|
@@ -7800,6 +9428,13 @@ func (o *LoweringOwner) awaitCallIfNeeded(ctx lowerFileContext, fun ast.Expr, ca
|
|
|
7800
9428
|
return call
|
|
7801
9429
|
}
|
|
7802
9430
|
|
|
9431
|
+
func parenthesizeAwaitedExpr(expr string) string {
|
|
9432
|
+
if strings.HasPrefix(expr, "await ") {
|
|
9433
|
+
return "(" + expr + ")"
|
|
9434
|
+
}
|
|
9435
|
+
return expr
|
|
9436
|
+
}
|
|
9437
|
+
|
|
7803
9438
|
func (o *LoweringOwner) genericTypeArgsExpr(ctx lowerFileContext, callee ast.Expr, typeArgExprs []ast.Expr) string {
|
|
7804
9439
|
signature := genericFunctionSignature(ctx, callee)
|
|
7805
9440
|
if signature == nil {
|
|
@@ -7883,7 +9518,7 @@ func (o *LoweringOwner) inferGenericTypeArg(
|
|
|
7883
9518
|
}
|
|
7884
9519
|
|
|
7885
9520
|
func (o *LoweringOwner) genericTypeDescriptorExpr(ctx lowerFileContext, typ types.Type) string {
|
|
7886
|
-
if typeParam, ok := types.Unalias(typ).(*types.TypeParam); ok &&
|
|
9521
|
+
if typeParam, ok := types.Unalias(typ).(*types.TypeParam); ok && typeParamInScope(ctx, typeParam) {
|
|
7887
9522
|
return "__typeArgs?.[" + strconv.Quote(typeParam.Obj().Name()) + "] ?? { type: " +
|
|
7888
9523
|
o.runtimeTypeInfoExpr(typ) + ", zero: () => " + o.lowerZeroValueExprFor(ctx, typ) + " }"
|
|
7889
9524
|
}
|
|
@@ -7921,7 +9556,16 @@ func (o *LoweringOwner) genericMethodDescriptorsForType(
|
|
|
7921
9556
|
methods = append(methods, method.Name()+": (receiver: any, ...args: any[]) => receiver."+method.Name()+"(...args)")
|
|
7922
9557
|
continue
|
|
7923
9558
|
}
|
|
7924
|
-
|
|
9559
|
+
receiver := "receiver"
|
|
9560
|
+
if sig, _ := method.Type().(*types.Signature); sig != nil {
|
|
9561
|
+
if recv := sig.Recv(); recv != nil {
|
|
9562
|
+
if _, ok := types.Unalias(recv.Type()).Underlying().(*types.Pointer); !ok {
|
|
9563
|
+
receiver = o.runtimeOwner.QualifiedHelper(RuntimeHelperPointerValue) + "(receiver)"
|
|
9564
|
+
}
|
|
9565
|
+
}
|
|
9566
|
+
}
|
|
9567
|
+
methods = append(methods, method.Name()+": (receiver: any, ...args: any[]) => "+
|
|
9568
|
+
"("+o.methodFunctionExpr(ctx, named.Origin(), method, method.Name())+" as any)("+receiver+", ...args)")
|
|
7925
9569
|
}
|
|
7926
9570
|
if len(methods) == 0 {
|
|
7927
9571
|
return ""
|
|
@@ -7951,6 +9595,18 @@ func methodFunctionName(receiver *types.Named, method string) string {
|
|
|
7951
9595
|
return receiver.Obj().Name() + "_" + method
|
|
7952
9596
|
}
|
|
7953
9597
|
|
|
9598
|
+
func methodReceiverNamedType(obj types.Object) *types.Named {
|
|
9599
|
+
fn, _ := obj.(*types.Func)
|
|
9600
|
+
if fn == nil {
|
|
9601
|
+
return nil
|
|
9602
|
+
}
|
|
9603
|
+
signature, _ := fn.Type().(*types.Signature)
|
|
9604
|
+
if signature == nil || signature.Recv() == nil {
|
|
9605
|
+
return nil
|
|
9606
|
+
}
|
|
9607
|
+
return receiverNamedType(signature.Recv().Type())
|
|
9608
|
+
}
|
|
9609
|
+
|
|
7954
9610
|
func (o *LoweringOwner) methodFunctionExpr(
|
|
7955
9611
|
ctx lowerFileContext,
|
|
7956
9612
|
receiver *types.Named,
|