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/decl.go
DELETED
|
@@ -1,801 +0,0 @@
|
|
|
1
|
-
package compiler
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"fmt"
|
|
5
|
-
"go/ast"
|
|
6
|
-
"go/token"
|
|
7
|
-
"go/types"
|
|
8
|
-
"slices"
|
|
9
|
-
"strings"
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
// linknameInfo holds parsed //go:linkname directive information.
|
|
13
|
-
type linknameInfo struct {
|
|
14
|
-
targetPkg string // target package path (e.g., "github.com/example/package")
|
|
15
|
-
targetName string // target symbol name (e.g., "CanHaveDecorators")
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// parseLinknameDirective checks if a doc comment contains a //go:linkname directive
|
|
19
|
-
// and returns the parsed information if found.
|
|
20
|
-
func parseLinknameDirective(doc *ast.CommentGroup) *linknameInfo {
|
|
21
|
-
if doc == nil {
|
|
22
|
-
return nil
|
|
23
|
-
}
|
|
24
|
-
for _, comment := range doc.List {
|
|
25
|
-
text := strings.TrimSpace(comment.Text)
|
|
26
|
-
if strings.HasPrefix(text, "//go:linkname ") {
|
|
27
|
-
// Format: //go:linkname localname importpath.name
|
|
28
|
-
parts := strings.Fields(text)
|
|
29
|
-
if len(parts) >= 3 {
|
|
30
|
-
target := parts[2]
|
|
31
|
-
// Split target into package path and symbol name
|
|
32
|
-
lastDot := strings.LastIndex(target, ".")
|
|
33
|
-
if lastDot > 0 {
|
|
34
|
-
return &linknameInfo{
|
|
35
|
-
targetPkg: target[:lastDot],
|
|
36
|
-
targetName: target[lastDot+1:],
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return nil
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// WriteDecls iterates through a slice of Go top-level declarations (`ast.Decl`)
|
|
46
|
-
// and translates each one into its TypeScript equivalent.
|
|
47
|
-
// It distinguishes between:
|
|
48
|
-
// - Function declarations (`ast.FuncDecl`):
|
|
49
|
-
// - If it's a regular function (no receiver), it delegates to `WriteFuncDeclAsFunction`.
|
|
50
|
-
// - Methods (with receivers) are handled within `WriteTypeSpec` when their
|
|
51
|
-
// associated struct/type is defined, so they are skipped here.
|
|
52
|
-
// - General declarations (`ast.GenDecl`), which can contain imports, constants,
|
|
53
|
-
// variables, or type definitions: It iterates through `d.Specs` and calls
|
|
54
|
-
// `WriteSpec` for each specification.
|
|
55
|
-
//
|
|
56
|
-
// Type declarations are sorted by dependencies to ensure referenced types are
|
|
57
|
-
// defined before types that reference them, avoiding initialization order issues.
|
|
58
|
-
// A newline is added after each processed declaration or spec group for readability.
|
|
59
|
-
// Unknown declaration types result in a printed diagnostic message.
|
|
60
|
-
func (c *GoToTSCompiler) WriteDecls(decls []ast.Decl) error {
|
|
61
|
-
// Separate type declarations from other declarations for dependency sorting
|
|
62
|
-
var typeSpecs []*ast.TypeSpec
|
|
63
|
-
var varSpecs []*ast.ValueSpec
|
|
64
|
-
var otherDecls []ast.Decl
|
|
65
|
-
var otherSpecs []ast.Spec
|
|
66
|
-
|
|
67
|
-
for _, decl := range decls {
|
|
68
|
-
switch d := decl.(type) {
|
|
69
|
-
case *ast.FuncDecl:
|
|
70
|
-
// Only handle top-level functions here. Methods are handled within WriteTypeSpec.
|
|
71
|
-
if d.Recv == nil {
|
|
72
|
-
otherDecls = append(otherDecls, d)
|
|
73
|
-
}
|
|
74
|
-
case *ast.GenDecl:
|
|
75
|
-
for _, spec := range d.Specs {
|
|
76
|
-
if typeSpec, ok := spec.(*ast.TypeSpec); ok {
|
|
77
|
-
typeSpecs = append(typeSpecs, typeSpec)
|
|
78
|
-
} else if varSpec, ok := spec.(*ast.ValueSpec); ok && d.Tok == token.VAR {
|
|
79
|
-
varSpecs = append(varSpecs, varSpec)
|
|
80
|
-
} else {
|
|
81
|
-
otherSpecs = append(otherSpecs, spec)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
default:
|
|
85
|
-
otherDecls = append(otherDecls, d)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Sort type declarations by dependencies
|
|
90
|
-
sortedTypeSpecs, err := c.sortTypeSpecsByDependencies(typeSpecs)
|
|
91
|
-
if err != nil {
|
|
92
|
-
// Surface the error instead of silently falling back
|
|
93
|
-
return fmt.Errorf("circular dependency detected sorting type declarations: %w", err)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Sort variable declarations by type dependencies
|
|
97
|
-
sortedVarSpecs, err := c.sortVarSpecsByTypeDependencies(varSpecs, typeSpecs)
|
|
98
|
-
if err != nil {
|
|
99
|
-
return fmt.Errorf("failed to sort variable declarations: %w", err)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Write non-type, non-var declarations first (imports, constants)
|
|
103
|
-
for _, spec := range otherSpecs {
|
|
104
|
-
if err := c.WriteSpec(spec); err != nil {
|
|
105
|
-
return err
|
|
106
|
-
}
|
|
107
|
-
c.tsw.WriteLine("") // Add space after spec
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Write sorted type declarations
|
|
111
|
-
for _, typeSpec := range sortedTypeSpecs {
|
|
112
|
-
if err := c.WriteSpec(typeSpec); err != nil {
|
|
113
|
-
return err
|
|
114
|
-
}
|
|
115
|
-
c.tsw.WriteLine("") // Add space after spec
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Write sorted variable declarations
|
|
119
|
-
for _, varSpec := range sortedVarSpecs {
|
|
120
|
-
if err := c.WriteSpec(varSpec); err != nil {
|
|
121
|
-
return err
|
|
122
|
-
}
|
|
123
|
-
c.tsw.WriteLine("") // Add space after spec
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Write function declarations last
|
|
127
|
-
for _, decl := range otherDecls {
|
|
128
|
-
switch d := decl.(type) {
|
|
129
|
-
case *ast.FuncDecl:
|
|
130
|
-
if err := c.WriteFuncDeclAsFunction(d); err != nil {
|
|
131
|
-
return err
|
|
132
|
-
}
|
|
133
|
-
c.tsw.WriteLine("") // Add space after function
|
|
134
|
-
default:
|
|
135
|
-
return fmt.Errorf("unknown decl: %#v", decl)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return nil
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// sortTypeSpecsByDependencies performs a topological sort of type specifications
|
|
143
|
-
// based on their dependencies to ensure referenced types are defined before
|
|
144
|
-
// types that reference them.
|
|
145
|
-
func (c *GoToTSCompiler) sortTypeSpecsByDependencies(typeSpecs []*ast.TypeSpec) ([]*ast.TypeSpec, error) {
|
|
146
|
-
if len(typeSpecs) <= 1 {
|
|
147
|
-
return typeSpecs, nil
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Build dependency graph
|
|
151
|
-
dependencies := make(map[string][]string) // typeName -> list of types it depends on
|
|
152
|
-
typeSpecMap := make(map[string]*ast.TypeSpec)
|
|
153
|
-
|
|
154
|
-
// First pass: collect all type names
|
|
155
|
-
for _, typeSpec := range typeSpecs {
|
|
156
|
-
typeName := typeSpec.Name.Name
|
|
157
|
-
typeSpecMap[typeName] = typeSpec
|
|
158
|
-
dependencies[typeName] = []string{}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Second pass: analyze dependencies
|
|
162
|
-
for _, typeSpec := range typeSpecs {
|
|
163
|
-
typeName := typeSpec.Name.Name
|
|
164
|
-
deps := c.extractTypeDependencies(typeSpec.Type, typeSpecMap)
|
|
165
|
-
dependencies[typeName] = deps
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Perform topological sort
|
|
169
|
-
sorted, err := c.topologicalSort(dependencies)
|
|
170
|
-
if err != nil {
|
|
171
|
-
return nil, err
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Build result in sorted order
|
|
175
|
-
var result []*ast.TypeSpec
|
|
176
|
-
for _, typeName := range sorted {
|
|
177
|
-
if typeSpec, exists := typeSpecMap[typeName]; exists {
|
|
178
|
-
result = append(result, typeSpec)
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return result, nil
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// extractTypeDependencies extracts only the dependencies that cause TypeScript initialization order issues.
|
|
186
|
-
// These are dependencies where the constructor of one type directly instantiates another type.
|
|
187
|
-
//
|
|
188
|
-
// TRUE dependencies (cause initialization issues):
|
|
189
|
-
// - Direct struct fields (non-pointer): type A struct { b B } -> A constructor calls new B()
|
|
190
|
-
// - Embedded struct fields: type A struct { B } -> A constructor calls new B()
|
|
191
|
-
// - Direct type aliases: type A B -> A directly wraps B
|
|
192
|
-
// - Array/slice of structs: type A []B -> needs B for default values
|
|
193
|
-
//
|
|
194
|
-
// FALSE dependencies (don't cause initialization issues):
|
|
195
|
-
// - Pointer fields: type A struct { b *B } -> just stores reference, no constructor call
|
|
196
|
-
// - Interface fields: type A struct { b SomeInterface } -> stores interface, no concrete instantiation
|
|
197
|
-
// - Map types: type A map[K]V -> map initialized empty, no constructor calls
|
|
198
|
-
// - Array/slice of pointers: type A []*B -> array of pointers, no constructor calls
|
|
199
|
-
func (c *GoToTSCompiler) extractTypeDependencies(typeExpr ast.Expr, typeSpecMap map[string]*ast.TypeSpec) []string {
|
|
200
|
-
var deps []string
|
|
201
|
-
|
|
202
|
-
switch t := typeExpr.(type) {
|
|
203
|
-
case *ast.Ident:
|
|
204
|
-
// Direct type reference (e.g., type MyType OtherType)
|
|
205
|
-
if _, isLocalType := typeSpecMap[t.Name]; isLocalType {
|
|
206
|
-
deps = append(deps, t.Name)
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
case *ast.StructType:
|
|
210
|
-
// Struct type - check field types, but be more selective
|
|
211
|
-
if t.Fields != nil {
|
|
212
|
-
for _, field := range t.Fields.List {
|
|
213
|
-
fieldDeps := c.extractStructFieldDependencies(field.Type, typeSpecMap)
|
|
214
|
-
deps = append(deps, fieldDeps...)
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
case *ast.ArrayType:
|
|
219
|
-
// Array/slice types don't create initialization dependencies
|
|
220
|
-
// Slices are reference types (initialized to null/empty), and arrays of structs
|
|
221
|
-
// don't require the element type constructor at declaration time.
|
|
222
|
-
// This allows circular references like: type A struct { BB []B }; type B struct { AA []A }
|
|
223
|
-
|
|
224
|
-
case *ast.StarExpr:
|
|
225
|
-
// Pointer types don't create initialization dependencies
|
|
226
|
-
// The pointed-to type doesn't need to be initialized when creating a pointer field
|
|
227
|
-
|
|
228
|
-
case *ast.MapType:
|
|
229
|
-
// Map types don't create initialization dependencies
|
|
230
|
-
// Maps are initialized empty, no constructor calls needed
|
|
231
|
-
|
|
232
|
-
case *ast.InterfaceType:
|
|
233
|
-
// Interface types don't create initialization dependencies
|
|
234
|
-
|
|
235
|
-
case *ast.FuncType:
|
|
236
|
-
// Function types don't create initialization dependencies
|
|
237
|
-
|
|
238
|
-
case *ast.SelectorExpr:
|
|
239
|
-
// External package types don't create local dependencies
|
|
240
|
-
|
|
241
|
-
// Add other type expressions as needed
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Sort dependencies for deterministic output
|
|
245
|
-
slices.Sort(deps)
|
|
246
|
-
return deps
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// extractStructFieldDependencies extracts dependencies from struct field types
|
|
250
|
-
func (c *GoToTSCompiler) extractStructFieldDependencies(fieldType ast.Expr, typeSpecMap map[string]*ast.TypeSpec) []string {
|
|
251
|
-
var deps []string
|
|
252
|
-
|
|
253
|
-
switch t := fieldType.(type) {
|
|
254
|
-
case *ast.Ident:
|
|
255
|
-
// Direct field type: struct { b B } - this requires B to be initialized
|
|
256
|
-
if _, isLocalType := typeSpecMap[t.Name]; isLocalType {
|
|
257
|
-
deps = append(deps, t.Name)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
case *ast.StarExpr:
|
|
261
|
-
// Pointer field: struct { b *B } - this doesn't require B initialization
|
|
262
|
-
// Pointers are just references, no constructor call needed
|
|
263
|
-
|
|
264
|
-
case *ast.ArrayType:
|
|
265
|
-
// Array/slice fields don't create initialization dependencies
|
|
266
|
-
// Slices are reference types (initialized to null/empty), and arrays of structs
|
|
267
|
-
// don't require the element type constructor at declaration time.
|
|
268
|
-
// This allows circular references like: type A struct { BB []B }; type B struct { AA []A }
|
|
269
|
-
|
|
270
|
-
case *ast.MapType:
|
|
271
|
-
// Map field: struct { b map[K]V } - maps don't require initialization dependencies
|
|
272
|
-
|
|
273
|
-
case *ast.InterfaceType:
|
|
274
|
-
// Interface field: struct { b SomeInterface } - no concrete type dependency
|
|
275
|
-
|
|
276
|
-
case *ast.FuncType:
|
|
277
|
-
// Function field: struct { b func() } - no dependency
|
|
278
|
-
|
|
279
|
-
// Handle other field types as needed
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return deps
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// sortVarSpecsByTypeDependencies sorts variable declarations based on their value dependencies
|
|
286
|
-
// to ensure that variables are initialized in the correct order (respecting JavaScript's TDZ).
|
|
287
|
-
// For example: var StdEncoding = NewEncoding(...) must come before var RawStdEncoding = StdEncoding.WithPadding(...)
|
|
288
|
-
func (c *GoToTSCompiler) sortVarSpecsByTypeDependencies(varSpecs []*ast.ValueSpec, typeSpecs []*ast.TypeSpec) ([]*ast.ValueSpec, error) {
|
|
289
|
-
if len(varSpecs) <= 1 {
|
|
290
|
-
return varSpecs, nil
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Build a map of variable names to their specs
|
|
294
|
-
varSpecMap := make(map[string]*ast.ValueSpec)
|
|
295
|
-
varNames := []string{}
|
|
296
|
-
for _, varSpec := range varSpecs {
|
|
297
|
-
if len(varSpec.Names) > 0 {
|
|
298
|
-
name := varSpec.Names[0].Name
|
|
299
|
-
varSpecMap[name] = varSpec
|
|
300
|
-
varNames = append(varNames, name)
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Build dependency graph: varName -> list of variables it depends on
|
|
305
|
-
dependencies := make(map[string][]string)
|
|
306
|
-
for _, name := range varNames {
|
|
307
|
-
dependencies[name] = []string{}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Extract value dependencies from initializer expressions
|
|
311
|
-
for _, varSpec := range varSpecs {
|
|
312
|
-
if len(varSpec.Names) == 0 {
|
|
313
|
-
continue
|
|
314
|
-
}
|
|
315
|
-
varName := varSpec.Names[0].Name
|
|
316
|
-
|
|
317
|
-
// Check initializer expressions for variable references
|
|
318
|
-
for _, value := range varSpec.Values {
|
|
319
|
-
deps := c.extractVarDependencies(value, varSpecMap)
|
|
320
|
-
dependencies[varName] = append(dependencies[varName], deps...)
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// Perform topological sort
|
|
325
|
-
sorted, err := c.topologicalSort(dependencies)
|
|
326
|
-
if err != nil {
|
|
327
|
-
return nil, err
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// Build result in sorted order
|
|
331
|
-
result := make([]*ast.ValueSpec, 0, len(varSpecs))
|
|
332
|
-
for _, varName := range sorted {
|
|
333
|
-
if spec, exists := varSpecMap[varName]; exists {
|
|
334
|
-
result = append(result, spec)
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
return result, nil
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// extractVarDependencies extracts variable dependencies from an initializer expression.
|
|
342
|
-
// It returns a list of variable names that the expression depends on.
|
|
343
|
-
func (c *GoToTSCompiler) extractVarDependencies(expr ast.Expr, varSpecMap map[string]*ast.ValueSpec) []string {
|
|
344
|
-
var deps []string
|
|
345
|
-
seen := make(map[string]bool)
|
|
346
|
-
|
|
347
|
-
ast.Inspect(expr, func(n ast.Node) bool {
|
|
348
|
-
if ident, ok := n.(*ast.Ident); ok {
|
|
349
|
-
// Check if this identifier refers to a package-level variable
|
|
350
|
-
if _, isVar := varSpecMap[ident.Name]; isVar {
|
|
351
|
-
if !seen[ident.Name] {
|
|
352
|
-
deps = append(deps, ident.Name)
|
|
353
|
-
seen[ident.Name] = true
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return true
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
return deps
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// topologicalSort performs a topological sort of the dependency graph
|
|
364
|
-
func (c *GoToTSCompiler) topologicalSort(dependencies map[string][]string) ([]string, error) {
|
|
365
|
-
// Kahn's algorithm for topological sorting with deterministic ordering
|
|
366
|
-
inDegree := make(map[string]int)
|
|
367
|
-
graph := make(map[string][]string)
|
|
368
|
-
|
|
369
|
-
// Initialize in-degree counts and reverse graph
|
|
370
|
-
for node := range dependencies {
|
|
371
|
-
inDegree[node] = 0
|
|
372
|
-
graph[node] = []string{}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// Build reverse graph and count in-degrees
|
|
376
|
-
for node, deps := range dependencies {
|
|
377
|
-
// Sort dependencies for consistent output
|
|
378
|
-
sortedDeps := make([]string, len(deps))
|
|
379
|
-
copy(sortedDeps, deps)
|
|
380
|
-
slices.Sort(sortedDeps)
|
|
381
|
-
|
|
382
|
-
for _, dep := range sortedDeps {
|
|
383
|
-
if _, exists := inDegree[dep]; exists {
|
|
384
|
-
graph[dep] = append(graph[dep], node)
|
|
385
|
-
inDegree[node]++
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// Sort neighbors in graph for consistency
|
|
391
|
-
for node := range graph {
|
|
392
|
-
slices.Sort(graph[node])
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// Find nodes with no incoming edges and sort them
|
|
396
|
-
var queue []string
|
|
397
|
-
for node, degree := range inDegree {
|
|
398
|
-
if degree == 0 {
|
|
399
|
-
queue = append(queue, node)
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
slices.Sort(queue) // Sort initial queue for deterministic output
|
|
403
|
-
|
|
404
|
-
var result []string
|
|
405
|
-
|
|
406
|
-
for len(queue) > 0 {
|
|
407
|
-
// Remove node from queue (already sorted)
|
|
408
|
-
current := queue[0]
|
|
409
|
-
queue = queue[1:]
|
|
410
|
-
result = append(result, current)
|
|
411
|
-
|
|
412
|
-
// Collect new zero-degree nodes
|
|
413
|
-
var newZeroNodes []string
|
|
414
|
-
for _, neighbor := range graph[current] {
|
|
415
|
-
inDegree[neighbor]--
|
|
416
|
-
if inDegree[neighbor] == 0 {
|
|
417
|
-
newZeroNodes = append(newZeroNodes, neighbor)
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// Sort new zero-degree nodes and add to queue
|
|
422
|
-
slices.Sort(newZeroNodes)
|
|
423
|
-
queue = append(queue, newZeroNodes...)
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
// Check for cycles
|
|
427
|
-
if len(result) != len(dependencies) {
|
|
428
|
-
// Find the remaining nodes to help debug the circular dependency
|
|
429
|
-
processed := make(map[string]bool)
|
|
430
|
-
for _, name := range result {
|
|
431
|
-
processed[name] = true
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
var remaining []string
|
|
435
|
-
for name := range dependencies {
|
|
436
|
-
if !processed[name] {
|
|
437
|
-
remaining = append(remaining, name)
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
slices.Sort(remaining)
|
|
441
|
-
|
|
442
|
-
return nil, fmt.Errorf("circular dependency detected in type declarations. Remaining types: %v", remaining)
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
return result, nil
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// WriteFuncDeclAsFunction translates a Go function declaration (`ast.FuncDecl`)
|
|
449
|
-
// that does not have a receiver (i.e., it's a regular function, not a method)
|
|
450
|
-
// into a TypeScript function.
|
|
451
|
-
// - Go documentation comments (`decl.Doc`) are preserved.
|
|
452
|
-
// - If the Go function is exported (name starts with an uppercase letter) or is
|
|
453
|
-
// the `main` function, the `export` keyword is added to the TypeScript output.
|
|
454
|
-
// - If the `Analysis` data indicates the function is asynchronous, the `async`
|
|
455
|
-
// keyword is prepended.
|
|
456
|
-
// - The function signature (parameters and return type) is translated using `WriteFuncType`,
|
|
457
|
-
// passing the `isAsync` status.
|
|
458
|
-
// - The function body (`decl.Body`) is translated using `WriteStmt`.
|
|
459
|
-
//
|
|
460
|
-
// This function specifically handles top-level functions; methods are generated
|
|
461
|
-
// by `WriteFuncDeclAsMethod` within the context of their type definition.
|
|
462
|
-
func (c *GoToTSCompiler) WriteFuncDeclAsFunction(decl *ast.FuncDecl) error {
|
|
463
|
-
if decl.Recv != nil {
|
|
464
|
-
// This function should not be called for methods.
|
|
465
|
-
// Methods are handled by WriteFuncDeclAsMethod within WriteTypeSpec.
|
|
466
|
-
return nil
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
// Check for //go:linkname directive on functions without a body
|
|
470
|
-
if linkInfo := parseLinknameDirective(decl.Doc); linkInfo != nil && decl.Body == nil {
|
|
471
|
-
// This is a linkname function - generate a re-export with type annotation
|
|
472
|
-
return c.writeLinknameFunction(decl, linkInfo)
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
if decl.Doc != nil {
|
|
476
|
-
c.WriteDoc(decl.Doc)
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// Export all functions for intra-package visibility
|
|
480
|
-
// This allows other files in the same package to import functions
|
|
481
|
-
c.tsw.WriteLiterally("export ")
|
|
482
|
-
|
|
483
|
-
// Check if this function is async using the analysis data
|
|
484
|
-
var isAsync bool
|
|
485
|
-
if obj := c.pkg.TypesInfo.Defs[decl.Name]; obj != nil {
|
|
486
|
-
isAsync = c.analysis.IsAsyncFunc(obj)
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
// Always make main function async (only in main package)
|
|
490
|
-
if decl.Name.Name == "main" && c.pkg.Name == "main" {
|
|
491
|
-
isAsync = true
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
if isAsync {
|
|
495
|
-
c.tsw.WriteLiterally("async ")
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
c.tsw.WriteLiterally("function ")
|
|
499
|
-
if err := c.WriteValueExpr(decl.Name); err != nil { // Function name is a value identifier
|
|
500
|
-
return fmt.Errorf("failed to write function name: %w", err)
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
// Write type parameters if present
|
|
504
|
-
if decl.Type.TypeParams != nil {
|
|
505
|
-
c.WriteTypeParameters(decl.Type.TypeParams)
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
// WriteFuncType needs to be aware if the function is async
|
|
509
|
-
c.WriteFuncType(decl.Type, isAsync) // Write signature (params, return type)
|
|
510
|
-
c.tsw.WriteLiterally(" ")
|
|
511
|
-
|
|
512
|
-
if c.hasNamedReturns(decl.Type.Results) {
|
|
513
|
-
c.tsw.WriteLine("{")
|
|
514
|
-
c.tsw.Indent(1)
|
|
515
|
-
|
|
516
|
-
// Declare named return variables and initialize them to their zero values
|
|
517
|
-
if err := c.writeNamedReturnDeclarations(decl.Type.Results); err != nil {
|
|
518
|
-
return fmt.Errorf("failed to write named return declarations: %w", err)
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
if err := c.WriteStmt(decl.Body); err != nil {
|
|
523
|
-
return fmt.Errorf("failed to write function body: %w", err)
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
if c.hasNamedReturns(decl.Type.Results) {
|
|
527
|
-
c.tsw.Indent(-1)
|
|
528
|
-
c.tsw.WriteLine("}")
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
return nil
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// writeLinknameFunction generates a TypeScript const re-export for a //go:linkname function.
|
|
535
|
-
// It generates: export const LocalName: (params) => ReturnType = alias.TargetName
|
|
536
|
-
//
|
|
537
|
-
// Unlike Go's //go:linkname, which does not perform type checking between the
|
|
538
|
-
// local declaration and the target symbol, the generated TypeScript code includes an
|
|
539
|
-
// explicit function type annotation. This means the TypeScript compiler will enforce
|
|
540
|
-
// that the declared parameter and return types match the actual target function type.
|
|
541
|
-
// Any mismatch will result in a TypeScript compilation error.
|
|
542
|
-
func (c *GoToTSCompiler) writeLinknameFunction(decl *ast.FuncDecl, info *linknameInfo) error {
|
|
543
|
-
// Find the import alias for the target package
|
|
544
|
-
alias := c.findImportAlias(info.targetPkg)
|
|
545
|
-
if alias == "" {
|
|
546
|
-
// Package not imported, write a comment and fall back to empty function
|
|
547
|
-
c.tsw.WriteLinef("//go:linkname target %s not found in imports", info.targetPkg)
|
|
548
|
-
c.tsw.WriteLiterally("export function ")
|
|
549
|
-
c.tsw.WriteLiterally(c.sanitizeIdentifier(decl.Name.Name))
|
|
550
|
-
c.WriteFuncType(decl.Type, false)
|
|
551
|
-
c.tsw.WriteLine(" {}")
|
|
552
|
-
return nil
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
// Generate: export const LocalName: (params) => ReturnType = alias.TargetName
|
|
556
|
-
c.tsw.WriteLiterally("export const ")
|
|
557
|
-
c.tsw.WriteLiterally(c.sanitizeIdentifier(decl.Name.Name))
|
|
558
|
-
c.tsw.WriteLiterally(": ")
|
|
559
|
-
|
|
560
|
-
// Write the function type as an arrow function type
|
|
561
|
-
c.WriteFuncTypeAsArrow(decl.Type)
|
|
562
|
-
|
|
563
|
-
c.tsw.WriteLiterally(" = ")
|
|
564
|
-
c.tsw.WriteLiterally(alias)
|
|
565
|
-
c.tsw.WriteLiterally(".")
|
|
566
|
-
c.tsw.WriteLiterally(info.targetName)
|
|
567
|
-
c.tsw.WriteLine("")
|
|
568
|
-
|
|
569
|
-
return nil
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
// findImportAlias finds the import alias used for a Go package path in the current file.
|
|
573
|
-
// Returns empty string if the package is not imported.
|
|
574
|
-
func (c *GoToTSCompiler) findImportAlias(pkgPath string) string {
|
|
575
|
-
// The importPath in analysis.Imports is stored as the TypeScript path (e.g., @goscript/pkg/path)
|
|
576
|
-
// We need to convert the Go package path to match
|
|
577
|
-
tsPath := translateGoImportPathToTypescriptModulePath(pkgPath)
|
|
578
|
-
|
|
579
|
-
for alias, imp := range c.analysis.Imports {
|
|
580
|
-
if imp.importPath == tsPath {
|
|
581
|
-
return alias
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
return ""
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
// WriteFuncDeclAsMethod translates a Go function declaration (`ast.FuncDecl`)
|
|
588
|
-
// that has a receiver (i.e., it's a method) into a TypeScript class method.
|
|
589
|
-
// - It preserves Go documentation comments (`decl.Doc`).
|
|
590
|
-
// - The method is declared as `public`.
|
|
591
|
-
// - If the `Analysis` data indicates the method is asynchronous, the `async`
|
|
592
|
-
// keyword is prepended.
|
|
593
|
-
// - The method name retains its original Go casing.
|
|
594
|
-
// - Parameters and return types are translated using `WriteFieldList` and
|
|
595
|
-
// `WriteTypeExpr`, respectively. Async methods have their return types
|
|
596
|
-
// wrapped in `Promise<>`.
|
|
597
|
-
// - The method body is translated. If the Go receiver has a name (e.g., `(s *MyStruct)`),
|
|
598
|
-
// a `const receiverName = this;` binding is generated at the start of the
|
|
599
|
-
// TypeScript method body to make `this` available via the Go receiver's name.
|
|
600
|
-
// If the method body requires deferred cleanup (`NeedsDefer`), the appropriate
|
|
601
|
-
// `using __defer = new $.DisposableStack()` (or `AsyncDisposableStack`)
|
|
602
|
-
// is also generated.
|
|
603
|
-
//
|
|
604
|
-
// This function assumes it is called only for `FuncDecl` nodes that are methods.
|
|
605
|
-
func (c *GoToTSCompiler) WriteFuncDeclAsMethod(decl *ast.FuncDecl) error {
|
|
606
|
-
_, err := c.writeMethodSignature(decl)
|
|
607
|
-
if err != nil {
|
|
608
|
-
return err
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
return c.writeMethodBodyWithReceiverBinding(decl, "this")
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
// writeNamedReturnDeclarations generates TypeScript variable declarations for named return parameters.
|
|
615
|
-
// It declares each named return variable with its appropriate type and zero value.
|
|
616
|
-
func (c *GoToTSCompiler) writeNamedReturnDeclarations(results *ast.FieldList) error {
|
|
617
|
-
if results == nil {
|
|
618
|
-
return nil
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
for _, field := range results.List {
|
|
622
|
-
for _, name := range field.Names {
|
|
623
|
-
c.tsw.WriteLiterallyf("let %s: ", c.sanitizeIdentifier(name.Name))
|
|
624
|
-
c.WriteTypeExpr(field.Type)
|
|
625
|
-
c.tsw.WriteLiterally(" = ")
|
|
626
|
-
c.WriteZeroValueForType(c.pkg.TypesInfo.TypeOf(field.Type))
|
|
627
|
-
c.tsw.WriteLine("")
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
return nil
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// hasNamedReturns checks if a function type has any named return parameters.
|
|
634
|
-
func (c *GoToTSCompiler) hasNamedReturns(results *ast.FieldList) bool {
|
|
635
|
-
if results == nil {
|
|
636
|
-
return false
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
for _, field := range results.List {
|
|
640
|
-
if len(field.Names) > 0 {
|
|
641
|
-
return true
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
return false
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
// writeMethodSignature writes the TypeScript method signature including async, public modifiers, name, parameters, and return type
|
|
648
|
-
func (c *GoToTSCompiler) writeMethodSignature(decl *ast.FuncDecl) (bool, error) {
|
|
649
|
-
if decl.Doc != nil {
|
|
650
|
-
c.WriteDoc(decl.Doc)
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// Determine if method is async
|
|
654
|
-
var isAsync bool
|
|
655
|
-
if obj := c.pkg.TypesInfo.Defs[decl.Name]; obj != nil {
|
|
656
|
-
isAsync = c.analysis.IsAsyncFunc(obj)
|
|
657
|
-
|
|
658
|
-
// Check if this method must be async due to interface constraints
|
|
659
|
-
if !isAsync && decl.Recv != nil && len(decl.Recv.List) > 0 {
|
|
660
|
-
// Get the receiver type
|
|
661
|
-
receiverType := decl.Recv.List[0].Type
|
|
662
|
-
if starExpr, ok := receiverType.(*ast.StarExpr); ok {
|
|
663
|
-
receiverType = starExpr.X
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
if ident, ok := receiverType.(*ast.Ident); ok {
|
|
667
|
-
// Get the named type for this receiver
|
|
668
|
-
if receiverObj := c.pkg.TypesInfo.Uses[ident]; receiverObj != nil {
|
|
669
|
-
if namedType, ok := receiverObj.Type().(*types.Named); ok {
|
|
670
|
-
// Check if this method must be async due to interface constraints
|
|
671
|
-
if c.analysis.MustBeAsyncDueToInterface(namedType, decl.Name.Name) {
|
|
672
|
-
isAsync = true
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
// Methods are typically public in the TS output
|
|
681
|
-
c.tsw.WriteLiterally("public ")
|
|
682
|
-
|
|
683
|
-
// Add async modifier if needed
|
|
684
|
-
if isAsync {
|
|
685
|
-
c.tsw.WriteLiterally("async ")
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
// Keep original Go casing for method names
|
|
689
|
-
if err := c.WriteValueExpr(decl.Name); err != nil { // Method name is a value identifier
|
|
690
|
-
return isAsync, err
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
// Write signature (parameters and return type)
|
|
694
|
-
funcType := decl.Type
|
|
695
|
-
c.tsw.WriteLiterally("(")
|
|
696
|
-
if funcType.Params != nil {
|
|
697
|
-
c.WriteFieldList(funcType.Params, true) // true = arguments
|
|
698
|
-
}
|
|
699
|
-
c.tsw.WriteLiterally(")")
|
|
700
|
-
|
|
701
|
-
// Handle return type
|
|
702
|
-
if funcType.Results != nil && len(funcType.Results.List) > 0 {
|
|
703
|
-
c.tsw.WriteLiterally(": ")
|
|
704
|
-
if isAsync {
|
|
705
|
-
c.tsw.WriteLiterally("Promise<")
|
|
706
|
-
}
|
|
707
|
-
if len(funcType.Results.List) == 1 {
|
|
708
|
-
// Single return value
|
|
709
|
-
resultType := funcType.Results.List[0].Type
|
|
710
|
-
c.WriteTypeExpr(resultType)
|
|
711
|
-
} else {
|
|
712
|
-
// Multiple return values -> tuple type
|
|
713
|
-
c.tsw.WriteLiterally("[")
|
|
714
|
-
first := true
|
|
715
|
-
for _, field := range funcType.Results.List {
|
|
716
|
-
// Each field may represent multiple return values (e.g., "a, b int")
|
|
717
|
-
count := len(field.Names)
|
|
718
|
-
if count == 0 {
|
|
719
|
-
count = 1 // Unnamed return value
|
|
720
|
-
}
|
|
721
|
-
for j := 0; j < count; j++ {
|
|
722
|
-
if !first {
|
|
723
|
-
c.tsw.WriteLiterally(", ")
|
|
724
|
-
}
|
|
725
|
-
first = false
|
|
726
|
-
c.WriteTypeExpr(field.Type)
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
c.tsw.WriteLiterally("]")
|
|
730
|
-
}
|
|
731
|
-
if isAsync {
|
|
732
|
-
c.tsw.WriteLiterally(">")
|
|
733
|
-
}
|
|
734
|
-
} else {
|
|
735
|
-
// No return value -> void
|
|
736
|
-
if isAsync {
|
|
737
|
-
c.tsw.WriteLiterally(": Promise<void>")
|
|
738
|
-
} else {
|
|
739
|
-
c.tsw.WriteLiterally(": void")
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
c.tsw.WriteLiterally(" ")
|
|
744
|
-
return isAsync, nil
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
// writeMethodBodyWithReceiverBinding writes the method body with optional receiver binding
|
|
748
|
-
// receiverTarget should be "this" for struct methods or "this._value" for named type methods
|
|
749
|
-
func (c *GoToTSCompiler) writeMethodBodyWithReceiverBinding(decl *ast.FuncDecl, receiverTarget string) error {
|
|
750
|
-
// Bind receiver name conditionally
|
|
751
|
-
if recvField := decl.Recv.List[0]; len(recvField.Names) > 0 {
|
|
752
|
-
recvName := recvField.Names[0].Name
|
|
753
|
-
if recvName != "_" {
|
|
754
|
-
// Check if receiver is actually used
|
|
755
|
-
var needsReceiverBinding bool
|
|
756
|
-
if obj := c.pkg.TypesInfo.Defs[decl.Name]; obj != nil {
|
|
757
|
-
needsReceiverBinding = c.analysis.IsReceiverUsed(obj)
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
c.tsw.WriteLine("{")
|
|
761
|
-
c.tsw.Indent(1)
|
|
762
|
-
|
|
763
|
-
if needsReceiverBinding {
|
|
764
|
-
// Sanitize the receiver name to avoid conflicts with TypeScript reserved words
|
|
765
|
-
sanitizedRecvName := c.sanitizeIdentifier(recvName)
|
|
766
|
-
c.tsw.WriteLinef("const %s = %s", sanitizedRecvName, receiverTarget)
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
// Add using statement if needed
|
|
770
|
-
if c.analysis.NeedsDefer(decl.Body) {
|
|
771
|
-
if c.analysis.IsInAsyncFunction(decl) {
|
|
772
|
-
c.tsw.WriteLine("await using __defer = new $.AsyncDisposableStack();")
|
|
773
|
-
} else {
|
|
774
|
-
c.tsw.WriteLine("using __defer = new $.DisposableStack();")
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
// Declare named return variables and initialize them to their zero values
|
|
779
|
-
if err := c.writeNamedReturnDeclarations(decl.Type.Results); err != nil {
|
|
780
|
-
return fmt.Errorf("failed to write named return declarations: %w", err)
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
// write method body without outer braces
|
|
784
|
-
for _, stmt := range decl.Body.List {
|
|
785
|
-
if err := c.WriteStmt(stmt); err != nil {
|
|
786
|
-
return fmt.Errorf("failed to write statement in function body: %w", err)
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
c.tsw.Indent(-1)
|
|
790
|
-
c.tsw.WriteLine("}")
|
|
791
|
-
|
|
792
|
-
return nil
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
// no named receiver, write whole body
|
|
796
|
-
if err := c.WriteStmt(decl.Body); err != nil {
|
|
797
|
-
return fmt.Errorf("failed to write function body: %w", err)
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
return nil
|
|
801
|
-
}
|