goscript 0.0.84 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +267 -243
- package/cmd/goscript/cmd-test.go +193 -0
- package/cmd/goscript/cmd-test_test.go +76 -0
- package/cmd/goscript/cmd_compile.go +70 -69
- package/cmd/goscript/cmd_compile_test.go +79 -0
- package/cmd/goscript/main.go +11 -5
- package/compiler/build-flags.go +38 -0
- package/compiler/compile-request.go +220 -0
- package/compiler/compiler.go +16 -1336
- package/compiler/compliance_test.go +188 -0
- package/compiler/config.go +6 -13
- package/compiler/diagnostic.go +70 -0
- package/compiler/gotest/owner.go +24 -0
- package/compiler/gotest/package-result.go +67 -0
- package/compiler/gotest/request.go +145 -0
- package/compiler/gotest/result.go +28 -0
- package/compiler/gotest/runner.go +588 -0
- package/compiler/gotest/runner_test.go +627 -0
- package/compiler/gotest/test.go +9 -0
- package/compiler/index.test.ts +28 -28
- package/compiler/index.ts +40 -72
- package/compiler/lowered-program.go +184 -0
- package/compiler/lowering.go +8072 -0
- package/compiler/override-facts.go +307 -0
- package/compiler/override-registry.go +283 -0
- package/compiler/override-registry_test.go +254 -0
- package/compiler/package-graph.go +254 -0
- package/compiler/package-graph_test.go +316 -0
- package/compiler/package-test-function.go +9 -0
- package/compiler/package-test-graph-package.go +40 -0
- package/compiler/package-test-graph-variant.go +105 -0
- package/compiler/package-test-graph.go +117 -0
- package/compiler/package-test-graph_test.go +144 -0
- package/compiler/result.go +13 -0
- package/compiler/runtime-contract.go +439 -0
- package/compiler/runtime-contract_test.go +104 -0
- package/compiler/semantic-model-types.go +113 -0
- package/compiler/semantic-model.go +1422 -0
- package/compiler/semantic-model_test.go +471 -0
- package/compiler/service.go +133 -0
- package/compiler/skeleton_test.go +1775 -0
- package/compiler/tsworkspace/owner.go +334 -0
- package/compiler/tsworkspace/owner_test.go +93 -0
- package/compiler/tsworkspace/result.go +17 -0
- package/compiler/typescript-emitter.go +1040 -0
- package/compiler/wasm/compile.go +2 -3
- package/compiler/wasm/compile_test.go +79 -0
- package/compiler/wasm_api.go +140 -124
- package/dist/compiler/index.d.ts +1 -3
- package/dist/compiler/index.js +31 -55
- package/dist/compiler/index.js.map +1 -1
- package/dist/gs/builtin/builtin.d.ts +33 -2
- package/dist/gs/builtin/builtin.js +217 -6
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +11 -3
- package/dist/gs/builtin/channel.js +12 -0
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +15 -1
- package/dist/gs/builtin/hostio.js +134 -49
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/index.d.ts +1 -0
- package/dist/gs/builtin/index.js +1 -0
- package/dist/gs/builtin/index.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +23 -3
- package/dist/gs/builtin/slice.js +216 -44
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +16 -2
- package/dist/gs/builtin/type.js +134 -21
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +5 -0
- package/dist/gs/builtin/varRef.js +23 -0
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +48 -44
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/bytes.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +20 -18
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/context/context.d.ts +5 -4
- package/dist/gs/context/context.js +10 -10
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
- package/dist/gs/crypto/rand/index.d.ts +5 -0
- package/dist/gs/crypto/rand/index.js +77 -0
- package/dist/gs/crypto/rand/index.js.map +1 -0
- package/dist/gs/embed/index.d.ts +7 -0
- package/dist/gs/embed/index.js +16 -0
- package/dist/gs/embed/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +4 -0
- package/dist/gs/encoding/json/index.js +178 -0
- package/dist/gs/encoding/json/index.js.map +1 -0
- package/dist/gs/errors/errors.d.ts +4 -0
- package/dist/gs/errors/errors.js +81 -0
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +4 -4
- package/dist/gs/fmt/fmt.js +42 -11
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +36 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +212 -2
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +825 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +163 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +449 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
- package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js +71 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
- package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
- package/dist/gs/go/internal/scannerhooks/index.js +5 -0
- package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
- package/dist/gs/go/scanner/index.d.ts +42 -0
- package/dist/gs/go/scanner/index.js +155 -0
- package/dist/gs/go/scanner/index.js.map +1 -0
- package/dist/gs/go/token/index.d.ts +187 -0
- package/dist/gs/go/token/index.js +578 -0
- package/dist/gs/go/token/index.js.map +1 -0
- package/dist/gs/internal/abi/index.d.ts +4 -0
- package/dist/gs/internal/abi/index.js +10 -0
- package/dist/gs/internal/abi/index.js.map +1 -1
- package/dist/gs/internal/bytealg/index.d.ts +2 -0
- package/dist/gs/internal/bytealg/index.js +14 -0
- package/dist/gs/internal/bytealg/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.d.ts +8 -2
- package/dist/gs/internal/byteorder/index.js +56 -25
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/godebug/index.d.ts +12 -0
- package/dist/gs/internal/godebug/index.js +30 -0
- package/dist/gs/internal/godebug/index.js.map +1 -0
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/index.d.ts +1 -0
- package/dist/gs/io/fs/index.js +1 -0
- package/dist/gs/io/fs/index.js.map +1 -1
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/readfile.js.map +1 -1
- package/dist/gs/io/fs/readlink.d.ts +8 -0
- package/dist/gs/io/fs/readlink.js +64 -0
- package/dist/gs/io/fs/readlink.js.map +1 -0
- package/dist/gs/io/fs/stat.js.map +1 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/fs/walk.d.ts +3 -3
- package/dist/gs/io/fs/walk.js +7 -7
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.d.ts +40 -6
- package/dist/gs/io/io.js +151 -26
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/maps/iter.d.ts +3 -3
- package/dist/gs/maps/iter.js +3 -3
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.d.ts +2 -2
- package/dist/gs/maps/maps.js +1 -1
- package/dist/gs/maps/maps.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +13 -4
- package/dist/gs/math/bits/index.js +66 -34
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/math/const.gs.d.ts +5 -5
- package/dist/gs/math/const.gs.js +4 -4
- package/dist/gs/math/const.gs.js.map +1 -1
- package/dist/gs/mime/index.d.ts +1 -0
- package/dist/gs/mime/index.js +50 -0
- package/dist/gs/mime/index.js.map +1 -0
- package/dist/gs/net/http/httptest/index.d.ts +11 -0
- package/dist/gs/net/http/httptest/index.js +21 -0
- package/dist/gs/net/http/httptest/index.js.map +1 -0
- package/dist/gs/net/http/index.d.ts +27 -0
- package/dist/gs/net/http/index.js +61 -0
- package/dist/gs/net/http/index.js.map +1 -0
- package/dist/gs/os/dir_unix.gs.js +2 -2
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +2 -4
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/rawconn_js.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/tempfile.gs.js +66 -9
- package/dist/gs/os/tempfile.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +9 -9
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js +165 -3
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.d.ts +3 -1
- package/dist/gs/path/filepath/path.js +133 -4
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/path/match.js.map +1 -1
- package/dist/gs/path/path.d.ts +4 -1
- package/dist/gs/path/path.js +16 -4
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +3 -3
- package/dist/gs/reflect/index.js +2 -2
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +3 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +9 -5
- package/dist/gs/reflect/type.js +233 -21
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/debug/index.d.ts +2 -0
- package/dist/gs/runtime/debug/index.js +8 -0
- package/dist/gs/runtime/debug/index.js.map +1 -0
- package/dist/gs/runtime/runtime.d.ts +35 -3
- package/dist/gs/runtime/runtime.js +72 -0
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +24 -5
- package/dist/gs/slices/slices.js +214 -5
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/slice.gs.d.ts +3 -3
- package/dist/gs/sort/slice.gs.js +6 -6
- package/dist/gs/sort/slice.gs.js.map +1 -1
- package/dist/gs/sort/sort.gs.d.ts +4 -4
- package/dist/gs/sort/sort.gs.js +11 -8
- package/dist/gs/sort/sort.gs.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/quote.gs.js.map +1 -1
- package/dist/gs/strings/builder.d.ts +1 -1
- package/dist/gs/strings/builder.js +3 -2
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
- package/dist/gs/sync/atomic/type.gs.js +0 -2
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +3 -0
- package/dist/gs/sync/sync.js +39 -0
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/constants.d.ts +36 -24
- package/dist/gs/syscall/constants.js +12 -0
- package/dist/gs/syscall/constants.js.map +1 -1
- package/dist/gs/syscall/errors.d.ts +2 -0
- package/dist/gs/syscall/errors.js +8 -0
- package/dist/gs/syscall/errors.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +43 -0
- package/dist/gs/syscall/fs.js +102 -0
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/syscall/js/index.d.ts +90 -0
- package/dist/gs/syscall/js/index.js +375 -0
- package/dist/gs/syscall/js/index.js.map +1 -0
- package/dist/gs/syscall/types.d.ts +22 -0
- package/dist/gs/syscall/types.js +45 -1
- package/dist/gs/syscall/types.js.map +1 -1
- package/dist/gs/testing/index.d.ts +1 -0
- package/dist/gs/testing/index.js +2 -0
- package/dist/gs/testing/index.js.map +1 -0
- package/dist/gs/testing/testing.d.ts +77 -0
- package/dist/gs/testing/testing.js +301 -0
- package/dist/gs/testing/testing.js.map +1 -0
- package/dist/gs/time/time.d.ts +41 -4
- package/dist/gs/time/time.js +205 -36
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.d.ts +23 -1
- package/dist/gs/unicode/unicode.js +79 -10
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
- package/dist/gs/unicode/utf8/utf8.js +24 -11
- package/dist/gs/unicode/utf8/utf8.js.map +1 -1
- package/dist/gs/unique/index.d.ts +11 -0
- package/dist/gs/unique/index.js +71 -0
- package/dist/gs/unique/index.js.map +1 -0
- package/go.mod +2 -2
- package/go.sum +9 -0
- package/gs/builtin/builtin.ts +266 -8
- package/gs/builtin/channel.ts +22 -0
- package/gs/builtin/hostio.test.ts +177 -0
- package/gs/builtin/hostio.ts +171 -56
- package/gs/builtin/index.ts +1 -0
- package/gs/builtin/runtime-contract.test.ts +356 -0
- package/gs/builtin/slice.ts +259 -50
- package/gs/builtin/type.ts +188 -30
- package/gs/builtin/varRef.ts +38 -1
- package/gs/bytes/buffer.gs.ts +48 -44
- package/gs/bytes/meta.json +8 -3
- package/gs/bytes/reader.gs.ts +20 -19
- package/gs/context/context.test.ts +41 -0
- package/gs/context/context.ts +22 -26
- package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
- package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
- package/gs/crypto/rand/index.test.ts +32 -0
- package/gs/crypto/rand/index.ts +90 -0
- package/gs/crypto/rand/meta.json +5 -0
- package/gs/embed/index.ts +20 -0
- package/gs/embed/meta.json +5 -0
- package/gs/encoding/json/index.test.ts +79 -0
- package/gs/encoding/json/index.ts +210 -0
- package/gs/errors/errors.test.ts +82 -0
- package/gs/errors/errors.ts +104 -0
- package/gs/fmt/fmt.ts +56 -16
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +95 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +300 -2
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +159 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1005 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +719 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +40 -0
- package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/meta.json +3 -1
- package/gs/github.com/klauspost/compress/internal/le/index.test.ts +36 -0
- package/gs/github.com/klauspost/compress/internal/le/index.ts +114 -0
- package/gs/go/internal/scannerhooks/index.test.ts +14 -0
- package/gs/go/internal/scannerhooks/index.ts +9 -0
- package/gs/go/scanner/index.test.ts +72 -0
- package/gs/go/scanner/index.ts +204 -0
- package/gs/go/token/index.test.ts +67 -0
- package/gs/go/token/index.ts +686 -0
- package/gs/internal/abi/index.test.ts +18 -0
- package/gs/internal/abi/index.ts +14 -0
- package/gs/internal/bytealg/index.test.ts +18 -0
- package/gs/internal/bytealg/index.ts +16 -0
- package/gs/internal/byteorder/index.test.ts +39 -0
- package/gs/internal/byteorder/index.ts +100 -27
- package/gs/internal/godebug/index.test.ts +16 -0
- package/gs/internal/godebug/index.ts +35 -0
- package/gs/io/fs/index.ts +1 -0
- package/gs/io/fs/meta.json +5 -0
- package/gs/io/fs/readlink.test.ts +43 -0
- package/gs/io/fs/readlink.ts +77 -0
- package/gs/io/fs/walk.test.ts +61 -0
- package/gs/io/fs/walk.ts +9 -9
- package/gs/io/io.ts +174 -31
- package/gs/io/meta.json +10 -2
- package/gs/maps/iter.ts +12 -6
- package/gs/maps/maps.ts +8 -6
- package/gs/math/bits/index.ts +103 -47
- package/gs/math/const.gs.test.ts +11 -5
- package/gs/math/const.gs.ts +5 -6
- package/gs/mime/index.ts +54 -0
- package/gs/net/http/httptest/index.ts +25 -0
- package/gs/net/http/index.test.ts +20 -0
- package/gs/net/http/index.ts +81 -0
- package/gs/os/dir_unix.gs.ts +2 -3
- package/gs/os/file_unix_js.test.ts +50 -0
- package/gs/os/meta.json +1 -2
- package/gs/os/tempfile.gs.test.ts +85 -0
- package/gs/os/tempfile.gs.ts +71 -11
- package/gs/os/types_js.gs.ts +11 -11
- package/gs/path/filepath/match.test.ts +31 -12
- package/gs/path/filepath/match.ts +178 -3
- package/gs/path/filepath/path.test.ts +25 -0
- package/gs/path/filepath/path.ts +159 -5
- package/gs/path/path.ts +20 -5
- package/gs/reflect/index.ts +2 -1
- package/gs/reflect/map.test.ts +19 -0
- package/gs/reflect/map.ts +4 -0
- package/gs/reflect/type.ts +298 -29
- package/gs/reflect/typefor.test.ts +75 -0
- package/gs/runtime/debug/index.test.ts +24 -0
- package/gs/runtime/debug/index.ts +8 -0
- package/gs/runtime/runtime.test.ts +19 -0
- package/gs/runtime/runtime.ts +98 -3
- package/gs/slices/slices.test.ts +94 -0
- package/gs/slices/slices.ts +245 -5
- package/gs/sort/meta.json +7 -0
- package/gs/sort/slice.gs.ts +16 -7
- package/gs/sort/sort.gs.ts +16 -13
- package/gs/strings/builder.ts +4 -3
- package/gs/sync/atomic/type.gs.ts +13 -14
- package/gs/sync/meta.json +3 -1
- package/gs/sync/sync.test.ts +36 -0
- package/gs/sync/sync.ts +39 -0
- package/gs/syscall/constants.ts +39 -24
- package/gs/syscall/errors.ts +10 -0
- package/gs/syscall/fs.ts +195 -0
- package/gs/syscall/js/index.ts +458 -0
- package/gs/syscall/js/meta.json +4 -0
- package/gs/syscall/net.test.ts +85 -0
- package/gs/syscall/types.ts +56 -0
- package/gs/testing/index.ts +1 -0
- package/gs/testing/meta.json +5 -0
- package/gs/testing/testing.test.ts +90 -0
- package/gs/testing/testing.ts +382 -0
- package/gs/time/time.test.ts +106 -0
- package/gs/time/time.ts +278 -57
- package/gs/unicode/unicode.test.ts +25 -0
- package/gs/unicode/unicode.ts +119 -9
- package/gs/unicode/utf8/utf8.test.ts +13 -0
- package/gs/unicode/utf8/utf8.ts +28 -16
- package/gs/unique/index.ts +91 -0
- package/package.json +14 -13
- package/compiler/analysis.go +0 -3475
- package/compiler/analysis_test.go +0 -338
- package/compiler/assignment.go +0 -580
- package/compiler/builtin_test.go +0 -92
- package/compiler/code-writer.go +0 -115
- package/compiler/compiler_test.go +0 -149
- package/compiler/composite-lit.go +0 -779
- package/compiler/config_test.go +0 -62
- package/compiler/constraint.go +0 -86
- package/compiler/decl.go +0 -801
- package/compiler/expr-call-async.go +0 -188
- package/compiler/expr-call-builtins.go +0 -208
- package/compiler/expr-call-helpers.go +0 -382
- package/compiler/expr-call-make.go +0 -318
- package/compiler/expr-call-type-conversion.go +0 -520
- package/compiler/expr-call.go +0 -413
- package/compiler/expr-selector.go +0 -343
- package/compiler/expr-star.go +0 -82
- package/compiler/expr-type.go +0 -442
- package/compiler/expr-value.go +0 -89
- package/compiler/expr.go +0 -773
- package/compiler/field.go +0 -183
- package/compiler/gs_dependencies_test.go +0 -298
- package/compiler/lit.go +0 -322
- package/compiler/output.go +0 -72
- package/compiler/primitive.go +0 -149
- package/compiler/protobuf.go +0 -697
- package/compiler/sanitize.go +0 -100
- package/compiler/spec-struct.go +0 -995
- package/compiler/spec-value.go +0 -540
- package/compiler/spec.go +0 -725
- package/compiler/stmt-assign.go +0 -664
- package/compiler/stmt-for.go +0 -266
- package/compiler/stmt-range.go +0 -475
- package/compiler/stmt-select.go +0 -262
- package/compiler/stmt-type-switch.go +0 -147
- package/compiler/stmt.go +0 -1308
- package/compiler/type-assert.go +0 -386
- package/compiler/type-info.go +0 -156
- package/compiler/type-utils.go +0 -207
- package/compiler/type.go +0 -892
package/compiler/stmt-assign.go
DELETED
|
@@ -1,664 +0,0 @@
|
|
|
1
|
-
package compiler
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"fmt"
|
|
5
|
-
"go/ast"
|
|
6
|
-
"go/token"
|
|
7
|
-
"go/types"
|
|
8
|
-
"strings"
|
|
9
|
-
|
|
10
|
-
"github.com/pkg/errors"
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
// WriteStmtAssign translates a Go assignment statement (`ast.AssignStmt`) into
|
|
14
|
-
// its TypeScript equivalent. It handles various forms of Go assignments:
|
|
15
|
-
//
|
|
16
|
-
// 1. **Multi-variable assignment from a single function call** (e.g., `a, b := fn()`):
|
|
17
|
-
// - Uses `writeMultiVarAssignFromCall` to generate `let [a, b] = fn_ts();`.
|
|
18
|
-
//
|
|
19
|
-
// 2. **Type assertion with comma-ok** (e.g., `val, ok := expr.(Type)`):
|
|
20
|
-
// - Uses `writeTypeAssertion` to generate `let { value: val, ok: ok } = $.typeAssert<Type_ts>(expr_ts, 'TypeName');`.
|
|
21
|
-
//
|
|
22
|
-
// 3. **Map lookup with comma-ok** (e.g., `val, ok := myMap[key]`):
|
|
23
|
-
// - Uses `writeMapLookupWithExists` to generate separate assignments for `val`
|
|
24
|
-
// (using `myMap_ts.get(key_ts) ?? zeroValue`) and `ok` (using `myMap_ts.has(key_ts)`).
|
|
25
|
-
//
|
|
26
|
-
// 4. **Channel receive with comma-ok** (e.g., `val, ok := <-ch`):
|
|
27
|
-
// - Uses `writeChannelReceiveWithOk` to generate `let { value: val, ok: ok } = await ch_ts.receiveWithOk();`.
|
|
28
|
-
//
|
|
29
|
-
// 5. **Discarded channel receive** (e.g., `<-ch` on RHS, no LHS vars):
|
|
30
|
-
// - Translates to `await ch_ts.receive();`.
|
|
31
|
-
//
|
|
32
|
-
// 6. **Single assignment** (e.g., `x = y`, `x := y`, `*p = y`, `x[i] = y`):
|
|
33
|
-
// - Uses `writeAssignmentCore` which handles:
|
|
34
|
-
// - Blank identifier `_` on LHS (evaluates RHS for side effects).
|
|
35
|
-
// - Assignment to dereferenced pointer `*p = val` -> `p_ts!.value = val_ts`.
|
|
36
|
-
// - Short declaration `x := y`: `let x = y_ts;`. If `x` is variable referenced, `let x: $.VarRef<T> = $.varRef(y_ts);`.
|
|
37
|
-
// - Regular assignment `x = y`, including compound assignments like `x += y`.
|
|
38
|
-
// - Assignment to map index `m[k] = v` using `$.mapSet`.
|
|
39
|
-
// - Struct value assignment `s1 = s2` becomes `s1 = s2.clone()` if `s2` is a struct.
|
|
40
|
-
//
|
|
41
|
-
// 7. **Multi-variable assignment with multiple RHS values** (e.g., `a, b = x, y`):
|
|
42
|
-
// - Uses `writeAssignmentCore` to generate `[a,b] = [x_ts, y_ts];` (or `let [a,b] = ...` for `:=`).
|
|
43
|
-
//
|
|
44
|
-
// The function ensures that the number of LHS and RHS expressions matches for
|
|
45
|
-
// most cases, erroring if they don't, except for specifically handled patterns
|
|
46
|
-
// like multi-assign from single call or discarded channel receive.
|
|
47
|
-
// It correctly applies `let` for `:=` (define) tokens and handles varRefing and
|
|
48
|
-
// cloning semantics based on type information and analysis.
|
|
49
|
-
func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) error {
|
|
50
|
-
// Handle multi-variable assignment from a single expression.
|
|
51
|
-
if len(exp.Lhs) > 1 && len(exp.Rhs) == 1 {
|
|
52
|
-
rhsExpr := exp.Rhs[0]
|
|
53
|
-
|
|
54
|
-
// Check for protobuf method calls first
|
|
55
|
-
if callExpr, ok := rhsExpr.(*ast.CallExpr); ok {
|
|
56
|
-
// Handle protobuf MarshalVT: data, err := msg.MarshalVT()
|
|
57
|
-
if len(exp.Lhs) == 2 && c.isProtobufMethodCall(callExpr, "MarshalVT") {
|
|
58
|
-
err := c.writeProtobufMarshalAssignment(exp.Lhs, callExpr, exp.Tok)
|
|
59
|
-
if err != nil {
|
|
60
|
-
return err
|
|
61
|
-
}
|
|
62
|
-
return nil
|
|
63
|
-
}
|
|
64
|
-
// Handle protobuf MarshalJSON: data, err := msg.MarshalJSON()
|
|
65
|
-
if len(exp.Lhs) == 2 && c.isProtobufMethodCall(callExpr, "MarshalJSON") {
|
|
66
|
-
err := c.writeProtobufMarshalJSONAssignment(exp.Lhs, callExpr, exp.Tok)
|
|
67
|
-
if err != nil {
|
|
68
|
-
return err
|
|
69
|
-
}
|
|
70
|
-
return nil
|
|
71
|
-
}
|
|
72
|
-
// Handle general function calls that return multiple values
|
|
73
|
-
return c.writeMultiVarAssignFromCall(exp.Lhs, callExpr, exp.Tok)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if typeAssertExpr, ok := rhsExpr.(*ast.TypeAssertExpr); ok {
|
|
77
|
-
return c.writeTypeAssert(exp.Lhs, typeAssertExpr, exp.Tok)
|
|
78
|
-
} else if indexExpr, ok := rhsExpr.(*ast.IndexExpr); ok {
|
|
79
|
-
// Check if this is a map lookup (comma-ok idiom)
|
|
80
|
-
if len(exp.Lhs) == 2 {
|
|
81
|
-
// Get the type of the indexed expression
|
|
82
|
-
if c.pkg != nil && c.pkg.TypesInfo != nil {
|
|
83
|
-
v, ok := c.pkg.TypesInfo.Types[indexExpr.X]
|
|
84
|
-
if ok {
|
|
85
|
-
// Check if it's a concrete map type
|
|
86
|
-
if _, isMap := v.Type.Underlying().(*types.Map); isMap {
|
|
87
|
-
return c.writeMapLookupWithExists(exp.Lhs, indexExpr, exp.Tok)
|
|
88
|
-
}
|
|
89
|
-
// Check if it's a type parameter constrained to be a map type
|
|
90
|
-
if typeParam, isTypeParam := v.Type.(*types.TypeParam); isTypeParam {
|
|
91
|
-
constraint := typeParam.Constraint()
|
|
92
|
-
if constraint != nil {
|
|
93
|
-
underlying := constraint.Underlying()
|
|
94
|
-
if iface, isInterface := underlying.(*types.Interface); isInterface {
|
|
95
|
-
if hasMapConstraint(iface) {
|
|
96
|
-
return c.writeMapLookupWithExists(exp.Lhs, indexExpr, exp.Tok)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
} else if unaryExpr, ok := rhsExpr.(*ast.UnaryExpr); ok && unaryExpr.Op == token.ARROW {
|
|
105
|
-
// Handle val, ok := <-channel
|
|
106
|
-
if len(exp.Lhs) == 2 {
|
|
107
|
-
return c.writeChannelReceiveWithOk(exp.Lhs, unaryExpr, exp.Tok)
|
|
108
|
-
}
|
|
109
|
-
// If LHS count is not 2, fall through to error or other handling
|
|
110
|
-
}
|
|
111
|
-
// If none of the specific multi-assign patterns match, fall through to the error check below
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Check for single-variable protobuf method calls before general assignment handling
|
|
115
|
-
if len(exp.Lhs) == 1 && len(exp.Rhs) == 1 {
|
|
116
|
-
if callExpr, ok := exp.Rhs[0].(*ast.CallExpr); ok {
|
|
117
|
-
// Handle protobuf UnmarshalVT: err = out.UnmarshalVT(data)
|
|
118
|
-
if c.isProtobufMethodCall(callExpr, "UnmarshalVT") {
|
|
119
|
-
return c.writeProtobufUnmarshalAssignment(exp.Lhs, callExpr)
|
|
120
|
-
}
|
|
121
|
-
// Handle protobuf UnmarshalJSON: err = out.UnmarshalJSON(data)
|
|
122
|
-
if c.isProtobufMethodCall(callExpr, "UnmarshalJSON") {
|
|
123
|
-
return c.writeProtobufUnmarshalJSONAssignment(exp.Lhs, callExpr, exp.Tok)
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Ensure LHS and RHS have the same length for valid Go code in these cases
|
|
129
|
-
if len(exp.Lhs) != len(exp.Rhs) {
|
|
130
|
-
// Special case: allow multiple LHS with single RHS if RHS can produce multiple values
|
|
131
|
-
// This handles cases like: x, y := getValue() where getValue() returns multiple values
|
|
132
|
-
// or other expressions that can produce multiple values
|
|
133
|
-
if len(exp.Rhs) == 1 {
|
|
134
|
-
// Allow single RHS expressions that can produce multiple values:
|
|
135
|
-
// - Function calls that return multiple values
|
|
136
|
-
// - Type assertions with comma-ok
|
|
137
|
-
// - Map lookups with comma-ok
|
|
138
|
-
// - Channel receives with comma-ok
|
|
139
|
-
// The Go type checker should have already verified this is valid
|
|
140
|
-
rhsExpr := exp.Rhs[0]
|
|
141
|
-
switch rhsExpr.(type) {
|
|
142
|
-
case *ast.CallExpr, *ast.TypeAssertExpr, *ast.IndexExpr, *ast.UnaryExpr:
|
|
143
|
-
// These expression types can potentially produce multiple values
|
|
144
|
-
// Let the general assignment logic handle them
|
|
145
|
-
default:
|
|
146
|
-
return fmt.Errorf("invalid assignment statement: LHS count (%d) != RHS count (%d)", len(exp.Lhs), len(exp.Rhs))
|
|
147
|
-
}
|
|
148
|
-
} else {
|
|
149
|
-
return fmt.Errorf("invalid assignment statement: LHS count (%d) != RHS count (%d)", len(exp.Lhs), len(exp.Rhs))
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Handle multi-variable assignment (e.g., swaps) using writeAssignmentCore
|
|
154
|
-
if len(exp.Lhs) > 1 {
|
|
155
|
-
// Need to handle := for multi-variable declarations
|
|
156
|
-
if exp.Tok == token.DEFINE {
|
|
157
|
-
c.tsw.WriteLiterally("let ") // Use let for multi-variable declarations
|
|
158
|
-
}
|
|
159
|
-
// For multi-variable assignments, we've already added the "let" if needed
|
|
160
|
-
if err := c.writeAssignmentCore(exp.Lhs, exp.Rhs, exp.Tok, false); err != nil {
|
|
161
|
-
return err
|
|
162
|
-
}
|
|
163
|
-
// Handle potential inline comment for multi-variable assignment
|
|
164
|
-
c.writeInlineComment(exp)
|
|
165
|
-
c.tsw.WriteLine("") // Add newline after the statement
|
|
166
|
-
return nil
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Handle single assignment using writeAssignmentCore
|
|
170
|
-
if len(exp.Lhs) == 1 {
|
|
171
|
-
// Check for type shadowing (e.g., field := field{...})
|
|
172
|
-
// In this case, we need to rename the variable to avoid TypeScript shadowing
|
|
173
|
-
if nodeInfo := c.analysis.NodeData[exp]; nodeInfo != nil && nodeInfo.ShadowingInfo != nil {
|
|
174
|
-
if lhsIdent, ok := exp.Lhs[0].(*ast.Ident); ok && lhsIdent.Name != "_" {
|
|
175
|
-
if renamedVar, hasTypeShadow := nodeInfo.ShadowingInfo.TypeShadowedVars[lhsIdent.Name]; hasTypeShadow {
|
|
176
|
-
if err := c.writeTypeShadowedAssignment(exp, lhsIdent.Name, renamedVar); err != nil {
|
|
177
|
-
return err
|
|
178
|
-
}
|
|
179
|
-
c.writeInlineComment(exp)
|
|
180
|
-
c.tsw.WriteLine("")
|
|
181
|
-
return nil
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
addDeclaration := exp.Tok == token.DEFINE
|
|
187
|
-
if err := c.writeAssignmentCore(exp.Lhs, exp.Rhs, exp.Tok, addDeclaration); err != nil {
|
|
188
|
-
return err
|
|
189
|
-
}
|
|
190
|
-
// Handle potential inline comment for single assignment
|
|
191
|
-
c.writeInlineComment(exp)
|
|
192
|
-
c.tsw.WriteLine("") // Add newline after the statement
|
|
193
|
-
return nil
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Should not reach here if LHS/RHS counts are valid and handled
|
|
197
|
-
return fmt.Errorf("unhandled assignment case")
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// writeInlineComment checks for and writes any inline comments associated with the given AST node.
|
|
201
|
-
// It is intended to be called immediately after writing the main statement/expression.
|
|
202
|
-
func (c *GoToTSCompiler) writeInlineComment(node ast.Node) {
|
|
203
|
-
if c.pkg == nil || c.pkg.Fset == nil || !node.End().IsValid() {
|
|
204
|
-
return
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
file := c.pkg.Fset.File(node.End())
|
|
208
|
-
if file == nil {
|
|
209
|
-
return
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
endLine := file.Line(node.End())
|
|
213
|
-
// Check comments associated *directly* with the node
|
|
214
|
-
for _, cg := range c.analysis.Cmap[node] {
|
|
215
|
-
if cg.Pos().IsValid() && file.Line(cg.Pos()) == endLine && cg.Pos() > node.End() {
|
|
216
|
-
commentText := strings.TrimSpace(strings.TrimPrefix(cg.Text(), "//"))
|
|
217
|
-
c.tsw.WriteLiterally(" // " + commentText)
|
|
218
|
-
return // Only write the first inline comment found
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// writeLHSTarget writes an LHS target expression for assignment contexts.
|
|
224
|
-
// It preserves the exact behavior used in WriteStmtAssign for selector, star, and index expressions,
|
|
225
|
-
// and avoids adding .value on identifiers.
|
|
226
|
-
func (c *GoToTSCompiler) writeLHSTarget(lhsExpr ast.Expr) error {
|
|
227
|
-
switch t := lhsExpr.(type) {
|
|
228
|
-
case *ast.Ident:
|
|
229
|
-
// Caller should have handled blank identifiers; write name without .value
|
|
230
|
-
c.WriteIdent(t, false)
|
|
231
|
-
return nil
|
|
232
|
-
case *ast.SelectorExpr:
|
|
233
|
-
if err := c.WriteValueExpr(t); err != nil {
|
|
234
|
-
return fmt.Errorf("failed to write selector expression in LHS: %w", err)
|
|
235
|
-
}
|
|
236
|
-
return nil
|
|
237
|
-
case *ast.StarExpr:
|
|
238
|
-
// Handle pointer dereference assignment: *p = value becomes p!.value = value
|
|
239
|
-
// Write the pointer variable directly without using WriteValueExpr when it's an identifier
|
|
240
|
-
switch operand := t.X.(type) {
|
|
241
|
-
case *ast.Ident:
|
|
242
|
-
c.WriteIdent(operand, false)
|
|
243
|
-
default:
|
|
244
|
-
if err := c.WriteValueExpr(t.X); err != nil {
|
|
245
|
-
return fmt.Errorf("failed to write star expression X in LHS: %w", err)
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
c.tsw.WriteLiterally("!.value")
|
|
249
|
-
return nil
|
|
250
|
-
case *ast.IndexExpr:
|
|
251
|
-
if err := c.WriteValueExpr(t); err != nil {
|
|
252
|
-
return fmt.Errorf("failed to write index expression in LHS: %w", err)
|
|
253
|
-
}
|
|
254
|
-
return nil
|
|
255
|
-
default:
|
|
256
|
-
return errors.Errorf("unhandled LHS expression in assignment: %T", lhsExpr)
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// lhsHasComplexTargets returns true if any LHS expression is a selector, star (dereference), or index expression.
|
|
261
|
-
func (c *GoToTSCompiler) lhsHasComplexTargets(lhs []ast.Expr) bool {
|
|
262
|
-
for _, e := range lhs {
|
|
263
|
-
switch e.(type) {
|
|
264
|
-
case *ast.SelectorExpr, *ast.StarExpr, *ast.IndexExpr:
|
|
265
|
-
return true
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return false
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// writeMultiVarAssignFromCall handles multi-variable assignment from a single function call.
|
|
272
|
-
func (c *GoToTSCompiler) writeMultiVarAssignFromCall(lhs []ast.Expr, callExpr *ast.CallExpr, tok token.Token) error {
|
|
273
|
-
// For token.DEFINE (:=), we need to check if any of the variables are already declared
|
|
274
|
-
// In Go, := can be used for redeclaration if at least one variable is new
|
|
275
|
-
if tok == token.DEFINE {
|
|
276
|
-
// For token.DEFINE (:=), we need to handle variable declarations differently
|
|
277
|
-
// In Go, := can redeclare existing variables if at least one is new
|
|
278
|
-
|
|
279
|
-
// First, identify which variables are new vs existing
|
|
280
|
-
newVars := make([]bool, len(lhs))
|
|
281
|
-
anyNewVars := false
|
|
282
|
-
allNewVars := true
|
|
283
|
-
|
|
284
|
-
// For multi-variable assignments with :=, we need to determine which variables
|
|
285
|
-
// are already in scope and which are new declarations
|
|
286
|
-
for i, lhsExpr := range lhs {
|
|
287
|
-
if ident, ok := lhsExpr.(*ast.Ident); ok && ident.Name != "_" {
|
|
288
|
-
// In Go, variables declared with := can be redeclared if at least one is new
|
|
289
|
-
// For TypeScript, we need to separately declare new variables
|
|
290
|
-
|
|
291
|
-
// Check if this variable is already in scope
|
|
292
|
-
// - If the variable is used elsewhere before this point, it's existing
|
|
293
|
-
// - Otherwise, it's a new variable being declared
|
|
294
|
-
isNew := true
|
|
295
|
-
|
|
296
|
-
// Check if the variable is used elsewhere in the code
|
|
297
|
-
if obj := c.pkg.TypesInfo.Uses[ident]; obj != nil {
|
|
298
|
-
// If it's in Uses, it's referenced elsewhere, so it exists
|
|
299
|
-
isNew = false
|
|
300
|
-
allNewVars = false
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
newVars[i] = isNew
|
|
304
|
-
if isNew {
|
|
305
|
-
anyNewVars = true
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Get function return types if available
|
|
311
|
-
var resultTypes []*types.Var
|
|
312
|
-
if callExpr.Fun != nil {
|
|
313
|
-
if funType := c.pkg.TypesInfo.TypeOf(callExpr.Fun); funType != nil {
|
|
314
|
-
if funcType, ok := funType.Underlying().(*types.Signature); ok {
|
|
315
|
-
if funcType.Results() != nil && funcType.Results().Len() > 0 {
|
|
316
|
-
for v := range funcType.Results().Variables() {
|
|
317
|
-
resultTypes = append(resultTypes, v)
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if allNewVars && anyNewVars {
|
|
325
|
-
// Check if any variable needs VarRef - if so, we need a different approach
|
|
326
|
-
anyNeedsVarRef := false
|
|
327
|
-
needsVarRefVars := make([]bool, len(lhs))
|
|
328
|
-
for i, lhsExpr := range lhs {
|
|
329
|
-
if ident, ok := lhsExpr.(*ast.Ident); ok && ident.Name != "_" {
|
|
330
|
-
if obj := c.pkg.TypesInfo.Defs[ident]; obj != nil {
|
|
331
|
-
if c.analysis.NeedsVarRef(obj) {
|
|
332
|
-
needsVarRefVars[i] = true
|
|
333
|
-
anyNeedsVarRef = true
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if anyNeedsVarRef {
|
|
340
|
-
// Use temp variables for destructuring, then wrap in VarRef as needed
|
|
341
|
-
c.tsw.WriteLiterally("let [")
|
|
342
|
-
for i, lhsExpr := range lhs {
|
|
343
|
-
if i != 0 {
|
|
344
|
-
c.tsw.WriteLiterally(", ")
|
|
345
|
-
}
|
|
346
|
-
if ident, ok := lhsExpr.(*ast.Ident); ok {
|
|
347
|
-
if ident.Name == "_" {
|
|
348
|
-
// Empty slot for blank identifier
|
|
349
|
-
} else if needsVarRefVars[i] {
|
|
350
|
-
c.tsw.WriteLiterally("_varref_tmp_")
|
|
351
|
-
c.tsw.WriteLiterally(ident.Name)
|
|
352
|
-
} else {
|
|
353
|
-
c.WriteIdent(ident, false)
|
|
354
|
-
}
|
|
355
|
-
} else {
|
|
356
|
-
c.WriteValueExpr(lhsExpr)
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
c.tsw.WriteLiterally("] = ")
|
|
360
|
-
c.WriteValueExpr(callExpr)
|
|
361
|
-
c.tsw.WriteLine("")
|
|
362
|
-
|
|
363
|
-
// Now declare the VarRef-wrapped variables
|
|
364
|
-
for i, lhsExpr := range lhs {
|
|
365
|
-
if ident, ok := lhsExpr.(*ast.Ident); ok && ident.Name != "_" && needsVarRefVars[i] {
|
|
366
|
-
c.tsw.WriteLiterally("let ")
|
|
367
|
-
c.WriteIdent(ident, false)
|
|
368
|
-
c.tsw.WriteLiterally(" = $.varRef(_varref_tmp_")
|
|
369
|
-
c.tsw.WriteLiterally(ident.Name)
|
|
370
|
-
// Add non-null assertion to handle cases where the tuple type includes null
|
|
371
|
-
c.tsw.WriteLiterally("!)")
|
|
372
|
-
c.tsw.WriteLine("")
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
return nil
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
c.tsw.WriteLiterally("let [")
|
|
379
|
-
|
|
380
|
-
for i, lhsExpr := range lhs {
|
|
381
|
-
if i != 0 {
|
|
382
|
-
c.tsw.WriteLiterally(", ")
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
if ident, ok := lhsExpr.(*ast.Ident); ok {
|
|
386
|
-
if ident.Name == "_" {
|
|
387
|
-
// For underscore variables, use empty slots in destructuring pattern
|
|
388
|
-
} else {
|
|
389
|
-
c.WriteIdent(ident, false)
|
|
390
|
-
}
|
|
391
|
-
} else {
|
|
392
|
-
c.WriteValueExpr(lhsExpr)
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
c.tsw.WriteLiterally("] = ")
|
|
396
|
-
c.WriteValueExpr(callExpr)
|
|
397
|
-
c.tsw.WriteLine("")
|
|
398
|
-
return nil
|
|
399
|
-
} else if anyNewVars {
|
|
400
|
-
// If only some variables are new, declare them separately before the assignment
|
|
401
|
-
// Declare each new variable with appropriate type
|
|
402
|
-
for i, lhsExpr := range lhs {
|
|
403
|
-
if ident, ok := lhsExpr.(*ast.Ident); ok && ident.Name != "_" && newVars[i] {
|
|
404
|
-
c.tsw.WriteLiterally("let ")
|
|
405
|
-
c.WriteIdent(ident, false)
|
|
406
|
-
// Add type annotation if we have type information
|
|
407
|
-
if i < len(resultTypes) {
|
|
408
|
-
c.tsw.WriteLiterally(": ")
|
|
409
|
-
c.WriteGoType(resultTypes[i].Type(), GoTypeContextGeneral)
|
|
410
|
-
}
|
|
411
|
-
c.tsw.WriteLine("")
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// First, collect all the selector expressions to identify variables that need to be initialized
|
|
418
|
-
hasSelectors := c.lhsHasComplexTargets(lhs)
|
|
419
|
-
|
|
420
|
-
// If we have selector expressions, we need to ensure variables are initialized
|
|
421
|
-
// before the destructuring assignment
|
|
422
|
-
if hasSelectors {
|
|
423
|
-
c.tsw.WriteLiterally("{")
|
|
424
|
-
c.tsw.WriteLine("")
|
|
425
|
-
|
|
426
|
-
// Write a temporary variable to hold the function call result
|
|
427
|
-
c.tsw.WriteLiterally(" const _tmp = ")
|
|
428
|
-
if err := c.WriteValueExpr(callExpr); err != nil {
|
|
429
|
-
return fmt.Errorf("failed to write RHS call expression in assignment: %w", err)
|
|
430
|
-
}
|
|
431
|
-
c.tsw.WriteLine("")
|
|
432
|
-
|
|
433
|
-
for i, lhsExpr := range lhs {
|
|
434
|
-
// Skip underscore variables
|
|
435
|
-
if ident, ok := lhsExpr.(*ast.Ident); ok && ident.Name == "_" {
|
|
436
|
-
continue
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// Write the LHS with indentation
|
|
440
|
-
c.tsw.WriteLiterally(" ")
|
|
441
|
-
if err := c.writeLHSTarget(lhsExpr); err != nil {
|
|
442
|
-
return err
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
// Write the assignment
|
|
446
|
-
c.tsw.WriteLiterallyf(" = _tmp[%d]", i)
|
|
447
|
-
// Always add a newline after each assignment
|
|
448
|
-
c.tsw.WriteLine("")
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// Close the block scope
|
|
452
|
-
c.tsw.WriteLiterally("}")
|
|
453
|
-
c.tsw.WriteLine("")
|
|
454
|
-
|
|
455
|
-
return nil
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
// For simple cases without selector expressions, use array destructuring
|
|
459
|
-
// Add semicolon before destructuring assignment to prevent TypeScript
|
|
460
|
-
// from interpreting it as array access on the previous line
|
|
461
|
-
if tok != token.DEFINE {
|
|
462
|
-
c.tsw.WriteLiterally(";")
|
|
463
|
-
}
|
|
464
|
-
c.tsw.WriteLiterally("[")
|
|
465
|
-
|
|
466
|
-
// Find the last non-blank identifier to avoid trailing commas
|
|
467
|
-
lastNonBlankIndex := -1
|
|
468
|
-
for i := len(lhs) - 1; i >= 0; i-- {
|
|
469
|
-
if ident, ok := lhs[i].(*ast.Ident); !ok || ident.Name != "_" {
|
|
470
|
-
lastNonBlankIndex = i
|
|
471
|
-
break
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
for i, lhsExpr := range lhs {
|
|
476
|
-
// Write comma before non-first elements
|
|
477
|
-
if i > 0 {
|
|
478
|
-
c.tsw.WriteLiterally(", ")
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
if ident, ok := lhsExpr.(*ast.Ident); ok {
|
|
482
|
-
// For underscore variables, use empty slots in destructuring pattern
|
|
483
|
-
if ident.Name != "_" {
|
|
484
|
-
c.WriteIdent(ident, false)
|
|
485
|
-
}
|
|
486
|
-
// For blank identifiers, we write nothing (empty slot)
|
|
487
|
-
} else {
|
|
488
|
-
if err := c.writeLHSTarget(lhsExpr); err != nil {
|
|
489
|
-
return err
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// Stop writing if we've reached the last non-blank element
|
|
494
|
-
if i == lastNonBlankIndex {
|
|
495
|
-
break
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
c.tsw.WriteLiterally("] = ")
|
|
499
|
-
|
|
500
|
-
c.WriteValueExpr(callExpr)
|
|
501
|
-
|
|
502
|
-
c.tsw.WriteLine("")
|
|
503
|
-
return nil
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// writeMapLookupWithExists handles the map comma-ok idiom: value, exists := myMap[key]
|
|
507
|
-
// Uses array destructuring with the tuple-returning $.mapGet function
|
|
508
|
-
func (c *GoToTSCompiler) writeMapLookupWithExists(lhs []ast.Expr, indexExpr *ast.IndexExpr, tok token.Token) error {
|
|
509
|
-
// First check that we have exactly two LHS expressions (value and exists)
|
|
510
|
-
if len(lhs) != 2 {
|
|
511
|
-
return fmt.Errorf("map comma-ok idiom requires exactly 2 variables on LHS, got %d", len(lhs))
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
// Check for blank identifiers
|
|
515
|
-
valueIsBlank := false
|
|
516
|
-
existsIsBlank := false
|
|
517
|
-
|
|
518
|
-
if valIdent, ok := lhs[0].(*ast.Ident); ok && valIdent.Name == "_" {
|
|
519
|
-
valueIsBlank = true
|
|
520
|
-
}
|
|
521
|
-
if existsIdent, ok := lhs[1].(*ast.Ident); ok && existsIdent.Name == "_" {
|
|
522
|
-
existsIsBlank = true
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// Use array destructuring with mapGet tuple return
|
|
526
|
-
if tok == token.DEFINE {
|
|
527
|
-
c.tsw.WriteLiterally("let ")
|
|
528
|
-
} else {
|
|
529
|
-
// Add semicolon before destructuring assignment to prevent TypeScript
|
|
530
|
-
// from interpreting it as array access on the previous line
|
|
531
|
-
c.tsw.WriteLiterally(";")
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
c.tsw.WriteLiterally("[")
|
|
535
|
-
|
|
536
|
-
// Write LHS variables, handling blanks
|
|
537
|
-
if !valueIsBlank {
|
|
538
|
-
if err := c.WriteValueExpr(lhs[0]); err != nil {
|
|
539
|
-
return err
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
// Note: for blank identifiers, we just omit the variable name entirely
|
|
543
|
-
|
|
544
|
-
c.tsw.WriteLiterally(", ")
|
|
545
|
-
|
|
546
|
-
if !existsIsBlank {
|
|
547
|
-
if err := c.WriteValueExpr(lhs[1]); err != nil {
|
|
548
|
-
return err
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
// Note: for blank identifiers, we just omit the variable name entirely
|
|
552
|
-
|
|
553
|
-
c.tsw.WriteLiterally("] = $.mapGet(")
|
|
554
|
-
|
|
555
|
-
// Write map expression
|
|
556
|
-
if err := c.WriteValueExpr(indexExpr.X); err != nil {
|
|
557
|
-
return err
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
c.tsw.WriteLiterally(", ")
|
|
561
|
-
|
|
562
|
-
// Write key expression
|
|
563
|
-
if err := c.WriteValueExpr(indexExpr.Index); err != nil {
|
|
564
|
-
return err
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
c.tsw.WriteLiterally(", ")
|
|
568
|
-
|
|
569
|
-
// Write the zero value for the map's value type
|
|
570
|
-
if tv, ok := c.pkg.TypesInfo.Types[indexExpr.X]; ok {
|
|
571
|
-
if mapType, isMap := tv.Type.Underlying().(*types.Map); isMap {
|
|
572
|
-
c.WriteZeroValueForType(mapType.Elem())
|
|
573
|
-
} else if typeParam, isTypeParam := tv.Type.(*types.TypeParam); isTypeParam {
|
|
574
|
-
// Handle type parameter constrained to be a map type
|
|
575
|
-
constraint := typeParam.Constraint()
|
|
576
|
-
if constraint != nil {
|
|
577
|
-
underlying := constraint.Underlying()
|
|
578
|
-
if iface, isInterface := underlying.(*types.Interface); isInterface {
|
|
579
|
-
if hasMapConstraint(iface) {
|
|
580
|
-
// Get the value type from the constraint
|
|
581
|
-
mapValueType := getMapValueTypeFromConstraint(iface)
|
|
582
|
-
if mapValueType != nil {
|
|
583
|
-
c.WriteZeroValueForType(mapValueType)
|
|
584
|
-
} else {
|
|
585
|
-
c.tsw.WriteLiterally("null")
|
|
586
|
-
}
|
|
587
|
-
} else {
|
|
588
|
-
c.tsw.WriteLiterally("null")
|
|
589
|
-
}
|
|
590
|
-
} else {
|
|
591
|
-
c.tsw.WriteLiterally("null")
|
|
592
|
-
}
|
|
593
|
-
} else {
|
|
594
|
-
c.tsw.WriteLiterally("null")
|
|
595
|
-
}
|
|
596
|
-
} else {
|
|
597
|
-
// Fallback zero value if type info is missing or not a map
|
|
598
|
-
c.tsw.WriteLiterally("null")
|
|
599
|
-
}
|
|
600
|
-
} else {
|
|
601
|
-
c.tsw.WriteLiterally("null")
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
c.tsw.WriteLiterally(")")
|
|
605
|
-
c.tsw.WriteLine("")
|
|
606
|
-
|
|
607
|
-
return nil
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
// writeTypeShadowedAssignment handles the case where a variable name shadows a type name
|
|
611
|
-
// used in its initialization (e.g., field := field{...}).
|
|
612
|
-
// In TypeScript, `let field = new field({...})` fails because the variable shadows the class
|
|
613
|
-
// before initialization due to the Temporal Dead Zone (TDZ). The TDZ extends from the
|
|
614
|
-
// start of the block scope to the point of initialization, so even capturing the type
|
|
615
|
-
// reference before the `let` declaration doesn't work - they're in the same block.
|
|
616
|
-
//
|
|
617
|
-
// We solve this by renaming the variable to avoid the conflict entirely:
|
|
618
|
-
//
|
|
619
|
-
// let field_ = $.markAsStructValue(new field({...}));
|
|
620
|
-
//
|
|
621
|
-
// Then we need to track that all subsequent references to `field` should use `field_`.
|
|
622
|
-
// This is stored in the analysis NodeInfo.IdentifierMapping.
|
|
623
|
-
func (c *GoToTSCompiler) writeTypeShadowedAssignment(exp *ast.AssignStmt, origName, renamedVar string) error {
|
|
624
|
-
if len(exp.Lhs) != 1 || len(exp.Rhs) != 1 {
|
|
625
|
-
return fmt.Errorf("type shadowing assignment must have exactly 1 LHS and 1 RHS")
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
lhsIdent, ok := exp.Lhs[0].(*ast.Ident)
|
|
629
|
-
if !ok {
|
|
630
|
-
return fmt.Errorf("type shadowing assignment LHS must be an identifier")
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// Check if this variable needs VarRef
|
|
634
|
-
obj := c.objectOfIdent(lhsIdent)
|
|
635
|
-
needsVarRef := obj != nil && c.analysis.NeedsVarRef(obj)
|
|
636
|
-
|
|
637
|
-
// Store the mapping so that subsequent references to this variable use the renamed version
|
|
638
|
-
if obj != nil {
|
|
639
|
-
c.renamedVars[obj] = renamedVar
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
if needsVarRef {
|
|
643
|
-
// For VarRef'd variables:
|
|
644
|
-
// let field_ = $.varRef($.markAsStructValue(new field({...})))
|
|
645
|
-
c.tsw.WriteLiterally("let ")
|
|
646
|
-
c.tsw.WriteLiterally(c.sanitizeIdentifier(renamedVar))
|
|
647
|
-
c.tsw.WriteLiterally(" = $.varRef(")
|
|
648
|
-
if err := c.WriteValueExpr(exp.Rhs[0]); err != nil {
|
|
649
|
-
return err
|
|
650
|
-
}
|
|
651
|
-
c.tsw.WriteLiterally(")")
|
|
652
|
-
} else {
|
|
653
|
-
// For non-VarRef variables:
|
|
654
|
-
// let field_ = $.markAsStructValue(new field({...}))
|
|
655
|
-
c.tsw.WriteLiterally("let ")
|
|
656
|
-
c.tsw.WriteLiterally(c.sanitizeIdentifier(renamedVar))
|
|
657
|
-
c.tsw.WriteLiterally(" = ")
|
|
658
|
-
if err := c.WriteValueExpr(exp.Rhs[0]); err != nil {
|
|
659
|
-
return err
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
return nil
|
|
664
|
-
}
|