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/spec.go
DELETED
|
@@ -1,725 +0,0 @@
|
|
|
1
|
-
package compiler
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"fmt"
|
|
5
|
-
"go/ast"
|
|
6
|
-
"go/types"
|
|
7
|
-
"strings"
|
|
8
|
-
|
|
9
|
-
"github.com/pkg/errors"
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
// WriteSpec is a dispatcher function that translates a Go specification node
|
|
13
|
-
// (`ast.Spec`) into its TypeScript equivalent. It handles different types of
|
|
14
|
-
// specifications found within `GenDecl` (general declarations):
|
|
15
|
-
// - `ast.ImportSpec` (import declarations): Delegates to `WriteImportSpec`.
|
|
16
|
-
// - `ast.ValueSpec` (variable or constant declarations): Delegates to `WriteValueSpec`.
|
|
17
|
-
// - `ast.TypeSpec` (type definitions like structs, interfaces): Delegates to `WriteTypeSpec`.
|
|
18
|
-
// If an unknown specification type is encountered, it returns an error.
|
|
19
|
-
func (c *GoToTSCompiler) WriteSpec(a ast.Spec) error {
|
|
20
|
-
switch d := a.(type) {
|
|
21
|
-
case *ast.ImportSpec:
|
|
22
|
-
c.WriteImportSpec(d)
|
|
23
|
-
case *ast.ValueSpec:
|
|
24
|
-
if err := c.WriteValueSpec(d); err != nil {
|
|
25
|
-
return err
|
|
26
|
-
}
|
|
27
|
-
case *ast.TypeSpec:
|
|
28
|
-
if err := c.WriteTypeSpec(d); err != nil {
|
|
29
|
-
return err
|
|
30
|
-
}
|
|
31
|
-
default:
|
|
32
|
-
return fmt.Errorf("unknown spec type: %T", a)
|
|
33
|
-
}
|
|
34
|
-
return nil
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
func (c *GoToTSCompiler) getEmbeddedFieldKeyName(fieldType types.Type) string {
|
|
38
|
-
trueType := fieldType
|
|
39
|
-
if ptr, isPtr := trueType.(*types.Pointer); isPtr {
|
|
40
|
-
trueType = ptr.Elem()
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if named, isNamed := trueType.(*types.Named); isNamed {
|
|
44
|
-
return named.Obj().Name()
|
|
45
|
-
} else {
|
|
46
|
-
// Fallback for unnamed embedded types, though less common for structs
|
|
47
|
-
fieldKeyName := trueType.String()
|
|
48
|
-
if len(fieldKeyName) > 0 {
|
|
49
|
-
fieldKeyName = strings.ToUpper(fieldKeyName[:1]) + fieldKeyName[1:]
|
|
50
|
-
}
|
|
51
|
-
if dotIndex := strings.LastIndex(fieldKeyName, "."); dotIndex != -1 {
|
|
52
|
-
fieldKeyName = fieldKeyName[dotIndex+1:]
|
|
53
|
-
}
|
|
54
|
-
return fieldKeyName
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
func (c *GoToTSCompiler) writeGetterSetter(fieldName string, fieldType types.Type, doc, comment *ast.CommentGroup, astType ast.Expr) {
|
|
59
|
-
// Use AST type information if available to preserve qualified names
|
|
60
|
-
// Note: getASTTypeString/getTypeString already includes "null |" for interface types
|
|
61
|
-
var fieldTypeStr string
|
|
62
|
-
if astType != nil {
|
|
63
|
-
fieldTypeStr = c.getASTTypeString(astType, fieldType)
|
|
64
|
-
} else {
|
|
65
|
-
fieldTypeStr = c.getTypeString(fieldType)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Generate getter
|
|
69
|
-
if doc != nil {
|
|
70
|
-
c.WriteDoc(doc)
|
|
71
|
-
}
|
|
72
|
-
if comment != nil {
|
|
73
|
-
c.WriteDoc(comment)
|
|
74
|
-
}
|
|
75
|
-
c.tsw.WriteLinef("public get %s(): %s {", fieldName, fieldTypeStr)
|
|
76
|
-
c.tsw.Indent(1)
|
|
77
|
-
c.tsw.WriteLinef("return this._fields.%s.value", fieldName)
|
|
78
|
-
c.tsw.Indent(-1)
|
|
79
|
-
c.tsw.WriteLine("}")
|
|
80
|
-
|
|
81
|
-
// Generate setter (no comments)
|
|
82
|
-
c.tsw.WriteLinef("public set %s(value: %s) {", fieldName, fieldTypeStr)
|
|
83
|
-
c.tsw.Indent(1)
|
|
84
|
-
c.tsw.WriteLinef("this._fields.%s.value = value", fieldName)
|
|
85
|
-
c.tsw.Indent(-1)
|
|
86
|
-
c.tsw.WriteLine("}")
|
|
87
|
-
c.tsw.WriteLine("")
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
func (c *GoToTSCompiler) writeVarRefedFieldInitializer(fieldName string, fieldType types.Type, isEmbedded bool, astType ast.Expr) {
|
|
91
|
-
c.tsw.WriteLiterally(fieldName)
|
|
92
|
-
c.tsw.WriteLiterally(": $.varRef(")
|
|
93
|
-
|
|
94
|
-
if isEmbedded {
|
|
95
|
-
c.writeEmbeddedFieldInitializer(fieldName, fieldType)
|
|
96
|
-
} else {
|
|
97
|
-
c.writeRegularFieldInitializer(fieldName, fieldType, astType)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
c.tsw.WriteLiterally(")")
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
func (c *GoToTSCompiler) writeEmbeddedFieldInitializer(fieldName string, fieldType types.Type) {
|
|
104
|
-
_, isPtr := fieldType.(*types.Pointer)
|
|
105
|
-
_, isInterface := fieldType.Underlying().(*types.Interface)
|
|
106
|
-
|
|
107
|
-
if isPtr || isInterface {
|
|
108
|
-
c.tsw.WriteLiterallyf("init?.%s ?? null", fieldName)
|
|
109
|
-
return
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Check if the embedded type is an interface
|
|
113
|
-
embeddedTypeUnderlying := fieldType
|
|
114
|
-
if named, isNamed := embeddedTypeUnderlying.(*types.Named); isNamed {
|
|
115
|
-
embeddedTypeUnderlying = named.Underlying()
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if _, isInterface := embeddedTypeUnderlying.(*types.Interface); isInterface {
|
|
119
|
-
// For interfaces, use the provided value or null instead of trying to instantiate
|
|
120
|
-
c.tsw.WriteLiterallyf("init?.%s ?? null", fieldName)
|
|
121
|
-
return
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// For structs, instantiate with provided fields
|
|
125
|
-
typeForNew := c.getTypeString(fieldType)
|
|
126
|
-
c.tsw.WriteLiterallyf("new %s(init?.%s)", typeForNew, fieldName)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
func (c *GoToTSCompiler) writeRegularFieldInitializer(fieldName string, fieldType types.Type, astType ast.Expr) {
|
|
130
|
-
// Check if this is a struct value type that needs cloning
|
|
131
|
-
if c.isStructValueType(fieldType) {
|
|
132
|
-
structTypeNameForClone := c.getTypeString(fieldType)
|
|
133
|
-
c.tsw.WriteLiterallyf("init?.%s ? $.markAsStructValue(init.%s.clone()) : new %s()", fieldName, fieldName, structTypeNameForClone)
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
c.tsw.WriteLiterallyf("init?.%s ?? ", fieldName)
|
|
138
|
-
|
|
139
|
-
// Priority 1: Check if this is a wrapper type
|
|
140
|
-
if c.isWrapperType(fieldType) {
|
|
141
|
-
// For wrapper types, use the zero value of the underlying type with type casting
|
|
142
|
-
if named, ok := fieldType.(*types.Named); ok {
|
|
143
|
-
c.WriteZeroValueForType(named.Underlying())
|
|
144
|
-
c.tsw.WriteLiterally(" as ")
|
|
145
|
-
c.WriteGoType(fieldType, GoTypeContextGeneral)
|
|
146
|
-
} else if alias, ok := fieldType.(*types.Alias); ok {
|
|
147
|
-
c.WriteZeroValueForType(alias.Underlying())
|
|
148
|
-
c.tsw.WriteLiterally(" as ")
|
|
149
|
-
c.WriteGoType(fieldType, GoTypeContextGeneral)
|
|
150
|
-
} else {
|
|
151
|
-
// Fallback to original behavior
|
|
152
|
-
c.WriteZeroValueForType(fieldType)
|
|
153
|
-
}
|
|
154
|
-
return
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Priority 2: Handle imported types with basic underlying types (like os.FileMode)
|
|
158
|
-
if c.isImportedBasicType(fieldType) {
|
|
159
|
-
if err := c.writeImportedBasicTypeZeroValue(fieldType); err != nil {
|
|
160
|
-
// Emit diagnostic and conservative zero value to avoid silent fallback
|
|
161
|
-
c.tsw.WriteCommentInlinef(" writeImportedBasicTypeZeroValue error: %v ", err)
|
|
162
|
-
c.WriteZeroValueForType(fieldType)
|
|
163
|
-
}
|
|
164
|
-
return
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Priority 3: Handle named types
|
|
168
|
-
if named, isNamed := fieldType.(*types.Named); isNamed {
|
|
169
|
-
c.writeNamedTypeZeroValue(named)
|
|
170
|
-
return
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Priority 4: Handle type aliases
|
|
174
|
-
if alias, isAlias := fieldType.(*types.Alias); isAlias {
|
|
175
|
-
c.writeTypeAliasZeroValue(alias, astType)
|
|
176
|
-
return
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
c.WriteZeroValueForType(fieldType)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
func (c *GoToTSCompiler) writeImportedBasicTypeZeroValue(fieldType types.Type) error {
|
|
183
|
-
if named, ok := fieldType.(*types.Named); ok {
|
|
184
|
-
underlying := named.Underlying()
|
|
185
|
-
// Write zero value of underlying type with type casting
|
|
186
|
-
c.WriteZeroValueForType(underlying)
|
|
187
|
-
c.tsw.WriteLiterally(" as ")
|
|
188
|
-
c.WriteGoType(fieldType, GoTypeContextGeneral)
|
|
189
|
-
return nil
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if alias, ok := fieldType.(*types.Alias); ok {
|
|
193
|
-
underlying := alias.Underlying()
|
|
194
|
-
// Write zero value of underlying type with type casting
|
|
195
|
-
c.WriteZeroValueForType(underlying)
|
|
196
|
-
c.tsw.WriteLiterally(" as ")
|
|
197
|
-
c.WriteGoType(fieldType, GoTypeContextGeneral)
|
|
198
|
-
return nil
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Reaching here indicates an internal inconsistency between isImportedBasicType and field kind
|
|
202
|
-
// Return an error to surface the issue to callers
|
|
203
|
-
return fmt.Errorf("writeImportedBasicTypeZeroValue: unexpected non-named/alias type %T", fieldType)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
func (c *GoToTSCompiler) writeNamedTypeZeroValue(named *types.Named) {
|
|
207
|
-
// Check if this is a wrapper type first
|
|
208
|
-
if c.isWrapperType(named) {
|
|
209
|
-
// For wrapper types, use the zero value of the underlying type with type casting
|
|
210
|
-
c.WriteZeroValueForType(named.Underlying())
|
|
211
|
-
c.tsw.WriteLiterally(" as ")
|
|
212
|
-
c.WriteGoType(named, GoTypeContextGeneral)
|
|
213
|
-
return
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Check if underlying type is an interface
|
|
217
|
-
if _, isInterface := named.Underlying().(*types.Interface); isInterface {
|
|
218
|
-
c.tsw.WriteLiterally("null")
|
|
219
|
-
return
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Check if underlying type is a struct
|
|
223
|
-
if _, isStruct := named.Underlying().(*types.Struct); isStruct {
|
|
224
|
-
c.WriteZeroValueForType(named)
|
|
225
|
-
return
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Check if underlying type is a function
|
|
229
|
-
if _, isFunc := named.Underlying().(*types.Signature); isFunc {
|
|
230
|
-
c.tsw.WriteLiterally("null")
|
|
231
|
-
return
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// For non-struct, non-interface named types, use constructor
|
|
235
|
-
c.tsw.WriteLiterally("new ")
|
|
236
|
-
c.WriteNamedType(named)
|
|
237
|
-
c.tsw.WriteLiterally("(")
|
|
238
|
-
c.WriteZeroValueForType(named.Underlying())
|
|
239
|
-
c.tsw.WriteLiterally(")")
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
func (c *GoToTSCompiler) writeTypeAliasZeroValue(alias *types.Alias, astType ast.Expr) {
|
|
243
|
-
// Check if this is a wrapper type first
|
|
244
|
-
if c.isWrapperType(alias) {
|
|
245
|
-
// For wrapper types, use the zero value of the underlying type with type casting
|
|
246
|
-
c.WriteZeroValueForType(alias.Underlying())
|
|
247
|
-
c.tsw.WriteLiterally(" as ")
|
|
248
|
-
c.WriteGoType(alias, GoTypeContextGeneral)
|
|
249
|
-
return
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Check if underlying type is an interface
|
|
253
|
-
if _, isInterface := alias.Underlying().(*types.Interface); isInterface {
|
|
254
|
-
c.tsw.WriteLiterally("null")
|
|
255
|
-
return
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Check if underlying type is a struct
|
|
259
|
-
if _, isStruct := alias.Underlying().(*types.Struct); isStruct {
|
|
260
|
-
c.WriteZeroValueForType(alias)
|
|
261
|
-
return
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Check if underlying type is a function
|
|
265
|
-
if _, isFunc := alias.Underlying().(*types.Signature); isFunc {
|
|
266
|
-
c.tsw.WriteLiterally("null")
|
|
267
|
-
return
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// For non-struct, non-interface type aliases, use constructor
|
|
271
|
-
c.tsw.WriteLiterally("new ")
|
|
272
|
-
// Use AST type information if available to preserve qualified names
|
|
273
|
-
if astType != nil {
|
|
274
|
-
c.WriteTypeExpr(astType)
|
|
275
|
-
} else {
|
|
276
|
-
c.WriteGoType(alias, GoTypeContextGeneral)
|
|
277
|
-
}
|
|
278
|
-
c.tsw.WriteLiterally("(")
|
|
279
|
-
c.WriteZeroValueForType(alias.Underlying())
|
|
280
|
-
c.tsw.WriteLiterally(")")
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// hasReceiverMethods checks if a type declaration has any receiver methods defined
|
|
284
|
-
func (c *GoToTSCompiler) hasReceiverMethods(typeName string) bool {
|
|
285
|
-
for _, fileSyntax := range c.pkg.Syntax {
|
|
286
|
-
for _, decl := range fileSyntax.Decls {
|
|
287
|
-
funcDecl, isFunc := decl.(*ast.FuncDecl)
|
|
288
|
-
if !isFunc || funcDecl.Recv == nil || len(funcDecl.Recv.List) == 0 {
|
|
289
|
-
continue
|
|
290
|
-
}
|
|
291
|
-
recvField := funcDecl.Recv.List[0]
|
|
292
|
-
recvType := recvField.Type
|
|
293
|
-
if starExpr, ok := recvType.(*ast.StarExpr); ok {
|
|
294
|
-
recvType = starExpr.X
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Check for both simple identifiers (FileMode) and generic types (FileMode[T])
|
|
298
|
-
var recvTypeName string
|
|
299
|
-
if ident, ok := recvType.(*ast.Ident); ok {
|
|
300
|
-
recvTypeName = ident.Name
|
|
301
|
-
} else if indexExpr, ok := recvType.(*ast.IndexExpr); ok {
|
|
302
|
-
if ident, ok := indexExpr.X.(*ast.Ident); ok {
|
|
303
|
-
recvTypeName = ident.Name
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if recvTypeName == typeName {
|
|
308
|
-
return true
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
return false
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// WriteNamedTypeWithMethods generates TypeScript code for Go named types that have methods.
|
|
316
|
-
// Instead of generating a class, it now generates:
|
|
317
|
-
// 1. A type alias for the underlying type
|
|
318
|
-
// 2. Function declarations for each method (TypeName_MethodName)
|
|
319
|
-
// 3. Function implementations for each method
|
|
320
|
-
func (c *GoToTSCompiler) WriteNamedTypeWithMethods(a *ast.TypeSpec) error {
|
|
321
|
-
className := a.Name.Name
|
|
322
|
-
|
|
323
|
-
// Add export for Go-exported types (but not if inside a function)
|
|
324
|
-
isInsideFunction := false
|
|
325
|
-
if nodeInfo := c.analysis.NodeData[a]; nodeInfo != nil {
|
|
326
|
-
isInsideFunction = nodeInfo.IsInsideFunction
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if !isInsideFunction {
|
|
330
|
-
c.tsw.WriteLiterally("export ")
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// Generate type alias instead of class
|
|
334
|
-
c.tsw.WriteLiterally("type ")
|
|
335
|
-
c.tsw.WriteLiterally(className)
|
|
336
|
-
c.tsw.WriteLiterally(" = ")
|
|
337
|
-
// Use AST-based type writing to preserve qualified names like os.FileInfo
|
|
338
|
-
c.WriteTypeExpr(a.Type)
|
|
339
|
-
c.tsw.WriteLine(";")
|
|
340
|
-
c.tsw.WriteLine("")
|
|
341
|
-
|
|
342
|
-
// Generate function declarations and implementations for each method
|
|
343
|
-
for _, fileSyntax := range c.pkg.Syntax {
|
|
344
|
-
for _, decl := range fileSyntax.Decls {
|
|
345
|
-
funcDecl, isFunc := decl.(*ast.FuncDecl)
|
|
346
|
-
if !isFunc || funcDecl.Recv == nil || len(funcDecl.Recv.List) == 0 {
|
|
347
|
-
continue
|
|
348
|
-
}
|
|
349
|
-
recvField := funcDecl.Recv.List[0]
|
|
350
|
-
recvType := recvField.Type
|
|
351
|
-
isPointerReceiver := false
|
|
352
|
-
if starExpr, ok := recvType.(*ast.StarExpr); ok {
|
|
353
|
-
recvType = starExpr.X
|
|
354
|
-
isPointerReceiver = true
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Check for both simple identifiers (FileMode) and generic types (FileMode[T])
|
|
358
|
-
var recvTypeName string
|
|
359
|
-
if ident, ok := recvType.(*ast.Ident); ok {
|
|
360
|
-
recvTypeName = ident.Name
|
|
361
|
-
} else if indexExpr, ok := recvType.(*ast.IndexExpr); ok {
|
|
362
|
-
if ident, ok := indexExpr.X.(*ast.Ident); ok {
|
|
363
|
-
recvTypeName = ident.Name
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
if recvTypeName == className {
|
|
368
|
-
c.tsw.WriteLiterally("export function ")
|
|
369
|
-
var isAsync bool
|
|
370
|
-
if obj := c.pkg.TypesInfo.Defs[funcDecl.Name]; obj != nil {
|
|
371
|
-
isAsync = c.analysis.IsAsyncFunc(obj)
|
|
372
|
-
}
|
|
373
|
-
if isAsync {
|
|
374
|
-
c.tsw.WriteLiterally("async ")
|
|
375
|
-
}
|
|
376
|
-
c.tsw.WriteLiterally(className)
|
|
377
|
-
c.tsw.WriteLiterally("_")
|
|
378
|
-
c.tsw.WriteLiterally(funcDecl.Name.Name)
|
|
379
|
-
c.tsw.WriteLiterally("(")
|
|
380
|
-
|
|
381
|
-
// First parameter is the receiver - use the original receiver parameter name
|
|
382
|
-
var receiverParamName string = "receiver" // default fallback
|
|
383
|
-
if funcDecl.Recv != nil && len(funcDecl.Recv.List) > 0 {
|
|
384
|
-
if len(funcDecl.Recv.List[0].Names) > 0 {
|
|
385
|
-
if name := funcDecl.Recv.List[0].Names[0]; name != nil && name.Name != "_" {
|
|
386
|
-
receiverParamName = name.Name
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
c.tsw.WriteLiterally(receiverParamName)
|
|
391
|
-
c.tsw.WriteLiterally(": ")
|
|
392
|
-
|
|
393
|
-
// For pointer receivers, use VarRef<T>
|
|
394
|
-
if isPointerReceiver {
|
|
395
|
-
c.tsw.WriteLiterally("$.VarRef<")
|
|
396
|
-
c.tsw.WriteLiterally(className)
|
|
397
|
-
c.tsw.WriteLiterally(">")
|
|
398
|
-
} else {
|
|
399
|
-
c.tsw.WriteLiterally(className)
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// Add other parameters
|
|
403
|
-
if funcDecl.Type.Params != nil && len(funcDecl.Type.Params.List) > 0 {
|
|
404
|
-
c.tsw.WriteLiterally(", ")
|
|
405
|
-
c.WriteFieldList(funcDecl.Type.Params, true) // true = arguments
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
c.tsw.WriteLiterally(")")
|
|
409
|
-
|
|
410
|
-
// Add return type
|
|
411
|
-
if funcDecl.Type.Results != nil && len(funcDecl.Type.Results.List) > 0 {
|
|
412
|
-
c.tsw.WriteLiterally(": ")
|
|
413
|
-
if isAsync {
|
|
414
|
-
c.tsw.WriteLiterally("Promise<")
|
|
415
|
-
}
|
|
416
|
-
if len(funcDecl.Type.Results.List) == 1 {
|
|
417
|
-
c.WriteTypeExpr(funcDecl.Type.Results.List[0].Type)
|
|
418
|
-
} else {
|
|
419
|
-
c.tsw.WriteLiterally("[")
|
|
420
|
-
first := true
|
|
421
|
-
for _, field := range funcDecl.Type.Results.List {
|
|
422
|
-
// Each field may represent multiple return values (e.g., "a, b int")
|
|
423
|
-
count := len(field.Names)
|
|
424
|
-
if count == 0 {
|
|
425
|
-
count = 1 // Unnamed return value
|
|
426
|
-
}
|
|
427
|
-
for j := 0; j < count; j++ {
|
|
428
|
-
if !first {
|
|
429
|
-
c.tsw.WriteLiterally(", ")
|
|
430
|
-
}
|
|
431
|
-
first = false
|
|
432
|
-
c.WriteTypeExpr(field.Type)
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
c.tsw.WriteLiterally("]")
|
|
436
|
-
}
|
|
437
|
-
if isAsync {
|
|
438
|
-
c.tsw.WriteLiterally(">")
|
|
439
|
-
}
|
|
440
|
-
} else {
|
|
441
|
-
if isAsync {
|
|
442
|
-
c.tsw.WriteLiterally(": Promise<void>")
|
|
443
|
-
} else {
|
|
444
|
-
c.tsw.WriteLiterally(": void")
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
c.tsw.WriteLine(" {")
|
|
449
|
-
c.tsw.Indent(1)
|
|
450
|
-
|
|
451
|
-
// Write method body with receiver as first parameter
|
|
452
|
-
if err := c.writeWrapperFunctionBody(funcDecl, className); err != nil {
|
|
453
|
-
return err
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
c.tsw.Indent(-1)
|
|
457
|
-
c.tsw.WriteLine("}")
|
|
458
|
-
c.tsw.WriteLine("")
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
return nil
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// writeWrapperFunctionBody writes the body of a wrapper function, treating the receiver as the first parameter
|
|
467
|
-
func (c *GoToTSCompiler) writeWrapperFunctionBody(decl *ast.FuncDecl, typeName string) error {
|
|
468
|
-
// Write function body statements directly - identifier mapping is handled by pre-computed analysis
|
|
469
|
-
if decl.Body != nil {
|
|
470
|
-
for _, stmt := range decl.Body.List {
|
|
471
|
-
if err := c.WriteStmt(stmt); err != nil {
|
|
472
|
-
return err
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
return nil
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// WriteTypeSpec writes the type specification to the output.
|
|
480
|
-
func (c *GoToTSCompiler) WriteTypeSpec(a *ast.TypeSpec) error {
|
|
481
|
-
if a.Doc != nil {
|
|
482
|
-
c.WriteDoc(a.Doc)
|
|
483
|
-
}
|
|
484
|
-
if a.Comment != nil {
|
|
485
|
-
c.WriteDoc(a.Comment)
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
switch t := a.Type.(type) {
|
|
489
|
-
case *ast.StructType:
|
|
490
|
-
return c.WriteStructTypeSpec(a, t)
|
|
491
|
-
case *ast.InterfaceType:
|
|
492
|
-
return c.WriteInterfaceTypeSpec(a, t)
|
|
493
|
-
default:
|
|
494
|
-
// Check if this type has receiver methods
|
|
495
|
-
if c.hasReceiverMethods(a.Name.Name) {
|
|
496
|
-
if named, ok := c.pkg.TypesInfo.Defs[a.Name].Type().(*types.Named); ok {
|
|
497
|
-
if _, isStruct := named.Underlying().(*types.Struct); isStruct {
|
|
498
|
-
return c.WriteNamedStructTypeSpec(a, named)
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
return c.WriteNamedTypeWithMethods(a)
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// Always export types for cross-file imports within the same package (but not if inside a function)
|
|
505
|
-
isInsideFunction := false
|
|
506
|
-
if nodeInfo := c.analysis.NodeData[a]; nodeInfo != nil {
|
|
507
|
-
isInsideFunction = nodeInfo.IsInsideFunction
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
if !isInsideFunction {
|
|
511
|
-
c.tsw.WriteLiterally("export ")
|
|
512
|
-
}
|
|
513
|
-
c.tsw.WriteLiterally("type ")
|
|
514
|
-
if err := c.WriteValueExpr(a.Name); err != nil {
|
|
515
|
-
return err
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
// Write type parameters if present (for generics)
|
|
519
|
-
if a.TypeParams != nil {
|
|
520
|
-
c.WriteTypeParameters(a.TypeParams)
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
c.tsw.WriteLiterally(" = ")
|
|
524
|
-
c.WriteTypeExpr(a.Type) // The aliased type
|
|
525
|
-
c.tsw.WriteLine(";")
|
|
526
|
-
}
|
|
527
|
-
return nil
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// WriteInterfaceTypeSpec writes the TypeScript type for a Go interface type.
|
|
531
|
-
func (c *GoToTSCompiler) WriteInterfaceTypeSpec(a *ast.TypeSpec, t *ast.InterfaceType) error {
|
|
532
|
-
// Add export for Go-exported interfaces (but not if inside a function)
|
|
533
|
-
isInsideFunction := false
|
|
534
|
-
if nodeInfo := c.analysis.NodeData[a]; nodeInfo != nil {
|
|
535
|
-
isInsideFunction = nodeInfo.IsInsideFunction
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
if !isInsideFunction {
|
|
539
|
-
c.tsw.WriteLiterally("export ")
|
|
540
|
-
}
|
|
541
|
-
c.tsw.WriteLiterally("type ")
|
|
542
|
-
if err := c.WriteValueExpr(a.Name); err != nil {
|
|
543
|
-
return err
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
// Write type parameters if present (for generics)
|
|
547
|
-
if a.TypeParams != nil {
|
|
548
|
-
c.WriteTypeParameters(a.TypeParams)
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
c.tsw.WriteLiterally(" = ")
|
|
552
|
-
// Get the types.Interface from the ast.InterfaceType.
|
|
553
|
-
// For an interface definition like `type MyInterface interface { M() }`,
|
|
554
|
-
// 't' is the *ast.InterfaceType representing `interface { M() }`.
|
|
555
|
-
// TypesInfo.TypeOf(t) will give the *types.Interface.
|
|
556
|
-
goType := c.pkg.TypesInfo.TypeOf(t)
|
|
557
|
-
if goType == nil {
|
|
558
|
-
return errors.Errorf("could not get type for interface AST node for %s", a.Name.Name)
|
|
559
|
-
}
|
|
560
|
-
ifaceType, ok := goType.(*types.Interface)
|
|
561
|
-
if !ok {
|
|
562
|
-
return errors.Errorf("expected *types.Interface, got %T for %s when processing interface literal", goType, a.Name.Name)
|
|
563
|
-
}
|
|
564
|
-
c.WriteInterfaceType(ifaceType, t) // Pass the *ast.InterfaceType for comment fetching
|
|
565
|
-
c.tsw.WriteLine("")
|
|
566
|
-
|
|
567
|
-
// Add code to register the interface with the runtime system
|
|
568
|
-
// Build full package path name for registration
|
|
569
|
-
interfaceName := a.Name.Name
|
|
570
|
-
pkgPath := c.pkg.Types.Path()
|
|
571
|
-
pkgName := c.pkg.Types.Name()
|
|
572
|
-
if pkgPath != "" && pkgName != "main" {
|
|
573
|
-
interfaceName = pkgPath + "." + interfaceName
|
|
574
|
-
} else if pkgName == "main" {
|
|
575
|
-
interfaceName = "main." + interfaceName
|
|
576
|
-
}
|
|
577
|
-
c.tsw.WriteLine("")
|
|
578
|
-
c.tsw.WriteLinef("$.registerInterfaceType(")
|
|
579
|
-
c.tsw.WriteLinef(" '%s',", interfaceName)
|
|
580
|
-
c.tsw.WriteLinef(" null, // Zero value for interface is null")
|
|
581
|
-
|
|
582
|
-
// Collect methods for the interface type
|
|
583
|
-
var interfaceMethods []*types.Func
|
|
584
|
-
if ifaceType != nil { // ifaceType is *types.Interface
|
|
585
|
-
for method := range ifaceType.ExplicitMethods() {
|
|
586
|
-
interfaceMethods = append(interfaceMethods, method)
|
|
587
|
-
}
|
|
588
|
-
// TODO: Handle embedded interface methods if necessary for full signature collection.
|
|
589
|
-
// For now, explicit methods are covered.
|
|
590
|
-
}
|
|
591
|
-
c.tsw.WriteLiterally(" [")
|
|
592
|
-
c.writeMethodSignatures(interfaceMethods)
|
|
593
|
-
c.tsw.WriteLiterally("]")
|
|
594
|
-
c.tsw.WriteLine("")
|
|
595
|
-
|
|
596
|
-
c.tsw.WriteLinef(");")
|
|
597
|
-
|
|
598
|
-
return nil
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// WriteImportSpec translates a Go import specification (`ast.ImportSpec`)
|
|
602
|
-
// into a TypeScript import statement.
|
|
603
|
-
//
|
|
604
|
-
// It extracts the Go import path (e.g., `"path/to/pkg"`) and determines the
|
|
605
|
-
// import alias/name for TypeScript. If the Go import has an explicit name
|
|
606
|
-
// (e.g., `alias "path/to/pkg"`), that alias is used. Otherwise, the package
|
|
607
|
-
// name is derived from the actual Go package name, not the import path.
|
|
608
|
-
//
|
|
609
|
-
// The Go path is then translated to a TypeScript module path using
|
|
610
|
-
// `translateGoPathToTypescriptPath`.
|
|
611
|
-
//
|
|
612
|
-
// Finally, it writes a TypeScript import statement like `import * as alias from "typescript/path/to/pkg";`
|
|
613
|
-
// and records the import details in `c.analysis.Imports` for later use (e.g.,
|
|
614
|
-
// resolving qualified identifiers).
|
|
615
|
-
func (c *GoToTSCompiler) WriteImportSpec(a *ast.ImportSpec) {
|
|
616
|
-
if a.Doc != nil {
|
|
617
|
-
c.WriteDoc(a.Doc)
|
|
618
|
-
}
|
|
619
|
-
if a.Comment != nil {
|
|
620
|
-
c.WriteDoc(a.Comment)
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
goPath := a.Path.Value[1 : len(a.Path.Value)-1]
|
|
624
|
-
|
|
625
|
-
// Determine the import name to use in TypeScript
|
|
626
|
-
var impName string
|
|
627
|
-
if a.Name != nil && a.Name.Name != "" && a.Name.Name != "." && a.Name.Name != "_" {
|
|
628
|
-
// Explicit alias provided: import alias "path/to/pkg"
|
|
629
|
-
// Skip dot imports (. "pkg") and blank imports (_ "pkg")
|
|
630
|
-
impName = a.Name.Name
|
|
631
|
-
} else if a.Name != nil && a.Name.Name == "_" {
|
|
632
|
-
// Blank import (_ "pkg") - skip entirely, these are for side effects only
|
|
633
|
-
return
|
|
634
|
-
} else {
|
|
635
|
-
// No explicit alias, or dot import - use the actual package name from type information
|
|
636
|
-
// This handles cases where package name differs from the last path segment
|
|
637
|
-
// For dot imports, we still need a valid identifier for the import
|
|
638
|
-
if actualName, err := getActualPackageName(goPath, c.pkg.Imports); err == nil {
|
|
639
|
-
impName = actualName
|
|
640
|
-
} else {
|
|
641
|
-
// Fallback to last segment of path if package not found in type information
|
|
642
|
-
pts := strings.Split(goPath, "/")
|
|
643
|
-
impName = pts[len(pts)-1]
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
// Apply sanitization to handle known names like "Promise" -> "PromiseType"
|
|
648
|
-
impName = c.sanitizeIdentifier(impName)
|
|
649
|
-
|
|
650
|
-
// All Go package imports are mapped to the @goscript/ scope.
|
|
651
|
-
// The TypeScript compiler will resolve these using tsconfig paths to either
|
|
652
|
-
// handwritten versions (in .goscript-assets) or transpiled versions (in goscript).
|
|
653
|
-
tsImportPath := translateGoImportPathToTypescriptModulePath(goPath)
|
|
654
|
-
|
|
655
|
-
c.analysis.Imports[impName] = &fileImport{
|
|
656
|
-
importPath: tsImportPath,
|
|
657
|
-
importVars: make(map[string]struct{}),
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
// Skip writing the import if it was already written as a synthetic import
|
|
661
|
-
// This prevents duplicate imports when a file needs an import both from
|
|
662
|
-
// its AST and for promoted methods from embedded structs
|
|
663
|
-
if syntheticImports := c.analysis.SyntheticImportsPerFile[c.currentFilePath]; syntheticImports != nil {
|
|
664
|
-
if _, isSynthetic := syntheticImports[impName]; isSynthetic {
|
|
665
|
-
return
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
c.tsw.WriteImport(impName, translateTypescriptModulePathToIndexImportPath(tsImportPath))
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
func (c *GoToTSCompiler) writeClonedFieldInitializer(fieldName string, fieldType types.Type, isEmbedded bool) {
|
|
673
|
-
c.tsw.WriteLiterally(fieldName)
|
|
674
|
-
c.tsw.WriteLiterally(": $.varRef(")
|
|
675
|
-
|
|
676
|
-
if isEmbedded {
|
|
677
|
-
isPointerToStruct := false
|
|
678
|
-
trueType := fieldType
|
|
679
|
-
if ptr, isPtr := trueType.(*types.Pointer); isPtr {
|
|
680
|
-
trueType = ptr.Elem()
|
|
681
|
-
isPointerToStruct = true
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
if named, isNamed := trueType.(*types.Named); isNamed {
|
|
685
|
-
_, isUnderlyingStruct := named.Underlying().(*types.Struct)
|
|
686
|
-
if isUnderlyingStruct && !isPointerToStruct { // Is a value struct
|
|
687
|
-
c.tsw.WriteLiterallyf("$.markAsStructValue(this._fields.%s.value.clone())", fieldName)
|
|
688
|
-
} else { // Is a pointer to a struct, or not a struct
|
|
689
|
-
c.tsw.WriteLiterallyf("this._fields.%s.value", fieldName)
|
|
690
|
-
}
|
|
691
|
-
} else {
|
|
692
|
-
c.tsw.WriteLiterallyf("this._fields.%s.value", fieldName)
|
|
693
|
-
}
|
|
694
|
-
} else {
|
|
695
|
-
// Check if this is a pointer type (nullable) or value type (non-nullable)
|
|
696
|
-
isPointerType := false
|
|
697
|
-
actualType := fieldType
|
|
698
|
-
if ptr, ok := fieldType.(*types.Pointer); ok {
|
|
699
|
-
isPointerType = true
|
|
700
|
-
actualType = ptr.Elem()
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
// Check if the actual type (after dereferencing pointer) is a struct
|
|
704
|
-
isValueTypeStruct := false
|
|
705
|
-
if named, ok := actualType.(*types.Named); ok {
|
|
706
|
-
if _, isStruct := named.Underlying().(*types.Struct); isStruct {
|
|
707
|
-
isValueTypeStruct = true
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
if isValueTypeStruct {
|
|
712
|
-
if isPointerType {
|
|
713
|
-
// Nullable struct pointer: field could be nil, use conditional
|
|
714
|
-
c.tsw.WriteLiterallyf("this._fields.%s.value ? $.markAsStructValue(this._fields.%s.value.clone()) : null", fieldName, fieldName)
|
|
715
|
-
} else {
|
|
716
|
-
// Non-nullable struct value: field is always present, no conditional needed
|
|
717
|
-
c.tsw.WriteLiterallyf("$.markAsStructValue(this._fields.%s.value.clone())", fieldName)
|
|
718
|
-
}
|
|
719
|
-
} else {
|
|
720
|
-
c.tsw.WriteLiterallyf("this._fields.%s.value", fieldName)
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
c.tsw.WriteLiterally(")")
|
|
725
|
-
}
|