goscript 0.1.4 → 0.2.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 +5 -2
- package/cmd/go_js_wasm_exec/main.go +201 -0
- package/cmd/go_js_wasm_exec/main_test.go +83 -0
- package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +7 -0
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript-wasm/main.go +38 -6
- package/compiler/compile-request.go +12 -9
- package/compiler/compliance_test.go +0 -1
- package/compiler/config.go +2 -0
- package/compiler/diagnostic.go +104 -12
- package/compiler/diagnostic_test.go +106 -0
- package/compiler/gotest/request.go +28 -0
- package/compiler/gotest/runner.go +354 -44
- package/compiler/gotest/runner_test.go +293 -1
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
- package/compiler/gotest/testdata/browserapi/go.mod +3 -0
- package/compiler/index.test.ts +23 -0
- package/compiler/lowered-program.go +33 -24
- package/compiler/lowering.go +746 -194
- package/compiler/lowering_bench_test.go +42 -27
- package/compiler/lowering_internal_test.go +18 -0
- package/compiler/override-facts.go +15 -0
- package/compiler/override-parity-verifier.go +450 -0
- package/compiler/override-parity.go +122 -0
- package/compiler/override-registry_test.go +559 -0
- package/compiler/protobuf-ts-binding.go +567 -0
- package/compiler/protobuf-ts-binding_test.go +402 -0
- package/compiler/runtime-contract.go +4 -0
- package/compiler/runtime-contract_test.go +2 -0
- package/compiler/semantic-model-types.go +9 -4
- package/compiler/semantic-model.go +282 -70
- package/compiler/semantic-model_test.go +82 -1
- package/compiler/service.go +21 -1
- package/compiler/skeleton_test.go +118 -10
- package/compiler/typescript-emitter.go +128 -13
- package/compiler/wasm/compile_test.go +37 -4
- package/compiler/{wasm_api.go → wasm-api.go} +57 -7
- package/dist/gs/builtin/hostio.js +5 -0
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +13 -2
- package/dist/gs/builtin/slice.js +187 -6
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +13 -5
- package/dist/gs/builtin/type.js +153 -60
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +11 -0
- package/dist/gs/builtin/varRef.js +57 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +10 -3
- package/dist/gs/compress/zlib/index.js +50 -16
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +114 -0
- package/dist/gs/encoding/json/index.js +544 -36
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +101 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +589 -0
- 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 +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +17 -11
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/errors.js +54 -30
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +2 -0
- package/dist/gs/go/scanner/index.js +29 -5
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.js +22 -6
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/index.d.ts +6 -0
- package/dist/gs/hash/index.js +20 -0
- package/dist/gs/hash/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.js +2 -2
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/goarch/index.d.ts +43 -3
- package/dist/gs/internal/goarch/index.js +42 -10
- package/dist/gs/internal/goarch/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js +26 -14
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js +4 -2
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +8 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.d.ts +2 -0
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +5 -0
- package/dist/gs/math/bits/index.js +16 -4
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.d.ts +16 -0
- package/dist/gs/mime/index.js +315 -6
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +12 -0
- package/dist/gs/net/http/httptest/index.js +85 -6
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +300 -5
- package/dist/gs/net/http/index.js +1598 -58
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +1 -1
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.d.ts +1 -0
- package/dist/gs/os/exec.gs.js +4 -8
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/index.d.ts +1 -1
- package/dist/gs/os/index.js +1 -1
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/os/proc.gs.d.ts +4 -0
- package/dist/gs/os/proc.gs.js +12 -6
- package/dist/gs/os/proc.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +1 -1
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/path.js +11 -7
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +5 -4
- package/dist/gs/reflect/index.js +4 -3
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +15 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +25 -6
- package/dist/gs/reflect/type.js +1475 -228
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +14 -6
- package/dist/gs/reflect/types.js +35 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +1 -0
- package/dist/gs/reflect/value.js +83 -41
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +4 -140
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +8 -2
- package/dist/gs/runtime/pprof/index.js +50 -30
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +5 -4
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js +5 -19
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/complex.gs.d.ts +3 -0
- package/dist/gs/strconv/complex.gs.js +148 -0
- package/dist/gs/strconv/complex.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +1 -0
- package/dist/gs/strconv/index.js +1 -0
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/builder.js +1 -1
- package/dist/gs/strings/reader.js +9 -5
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js +15 -7
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.d.ts +5 -0
- package/dist/gs/strings/strings.js +57 -5
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/doc_64.gs.js +7 -6
- package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js +9 -9
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js +2 -2
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/testing/testing.js +55 -13
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.d.ts +24 -1
- package/dist/gs/time/time.js +43 -3
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unique/index.js +7 -1
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +3 -3
- package/go.sum +16 -0
- package/gs/builtin/hostio.test.ts +16 -0
- package/gs/builtin/hostio.ts +7 -0
- package/gs/builtin/runtime-contract.test.ts +246 -21
- package/gs/builtin/slice.ts +269 -24
- package/gs/builtin/type.ts +226 -59
- package/gs/builtin/varRef.ts +85 -2
- package/gs/bytes/buffer.gs.ts +1 -1
- package/gs/bytes/reader.gs.ts +1 -1
- package/gs/compress/zlib/index.test.ts +62 -1
- package/gs/compress/zlib/index.ts +53 -16
- package/gs/compress/zlib/parity.json +51 -0
- package/gs/encoding/json/index.test.ts +360 -6
- package/gs/encoding/json/index.ts +679 -38
- package/gs/encoding/json/parity.json +81 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +373 -3
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +893 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +18 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +17 -11
- package/gs/github.com/pkg/errors/errors.ts +54 -30
- package/gs/go/scanner/index.test.ts +39 -56
- package/gs/go/scanner/index.ts +33 -5
- package/gs/go/scanner/parity.json +27 -0
- package/gs/go/token/index.ts +22 -6
- package/gs/hash/index.test.ts +20 -33
- package/gs/hash/index.ts +28 -0
- package/gs/hash/parity.json +21 -0
- package/gs/internal/byteorder/index.test.ts +2 -2
- package/gs/internal/byteorder/index.ts +2 -2
- package/gs/internal/goarch/index.test.ts +32 -0
- package/gs/internal/goarch/index.ts +45 -13
- package/gs/internal/goarch/parity.json +144 -0
- package/gs/io/fs/fs.ts +26 -14
- package/gs/io/fs/readdir.ts +4 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.ts +1 -0
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +23 -4
- package/gs/math/bits/parity.json +156 -0
- package/gs/mime/index.test.ts +90 -0
- package/gs/mime/index.ts +369 -6
- package/gs/mime/parity.json +36 -0
- package/gs/net/http/httptest/index.test.ts +98 -2
- package/gs/net/http/httptest/index.ts +101 -6
- package/gs/net/http/httptest/parity.json +15 -0
- package/gs/net/http/index.test.ts +781 -12
- package/gs/net/http/index.ts +1860 -139
- package/gs/net/http/meta.json +16 -1
- package/gs/net/http/parity.json +193 -0
- package/gs/os/dir_unix.gs.ts +1 -1
- package/gs/os/error.gs.ts +1 -1
- package/gs/os/exec.gs.ts +4 -8
- package/gs/os/exec_posix.gs.ts +1 -1
- package/gs/os/index.test.ts +9 -0
- package/gs/os/index.ts +1 -0
- package/gs/os/parity.json +9 -0
- package/gs/os/proc.gs.ts +18 -5
- package/gs/os/proc.test.ts +26 -0
- package/gs/os/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +1 -1
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- package/gs/reflect/field.test.ts +37 -15
- package/gs/reflect/function-types.test.ts +518 -22
- package/gs/reflect/index.ts +8 -6
- package/gs/reflect/map.ts +20 -0
- package/gs/reflect/meta.json +6 -4
- package/gs/reflect/parity.json +234 -0
- package/gs/reflect/sliceat.test.ts +156 -0
- package/gs/reflect/structof.test.ts +401 -0
- package/gs/reflect/type.ts +1961 -317
- package/gs/reflect/typefor.test.ts +530 -10
- package/gs/reflect/types.ts +43 -18
- package/gs/reflect/value.ts +105 -45
- package/gs/reflect/visiblefields.ts +5 -168
- package/gs/runtime/parity.json +24 -0
- package/gs/runtime/pprof/index.test.ts +29 -7
- package/gs/runtime/pprof/index.ts +56 -30
- package/gs/runtime/pprof/parity.json +27 -0
- package/gs/runtime/runtime.test.ts +3 -1
- package/gs/runtime/runtime.ts +4 -3
- package/gs/runtime/trace/index.test.ts +5 -3
- package/gs/runtime/trace/index.ts +8 -20
- package/gs/runtime/trace/parity.json +36 -0
- package/gs/strconv/atoi.gs.ts +1 -1
- package/gs/strconv/complex.gs.ts +174 -0
- package/gs/strconv/complex.test.ts +65 -0
- package/gs/strconv/index.ts +1 -0
- package/gs/strconv/parity.json +120 -0
- package/gs/strings/builder.ts +1 -1
- package/gs/strings/parity.json +186 -0
- package/gs/strings/reader.ts +9 -5
- package/gs/strings/replace.ts +15 -7
- package/gs/strings/strings.test.ts +22 -2
- package/gs/strings/strings.ts +64 -6
- package/gs/sync/atomic/doc_64.gs.ts +6 -7
- package/gs/sync/atomic/doc_64.test.ts +43 -0
- package/gs/sync/atomic/type.gs.ts +9 -9
- package/gs/sync/atomic/value.gs.ts +2 -2
- package/gs/syscall/env.ts +29 -14
- package/gs/testing/testing.test.ts +67 -0
- package/gs/testing/testing.ts +87 -19
- package/gs/time/parity.json +225 -0
- package/gs/time/time.test.ts +20 -2
- package/gs/time/time.ts +49 -7
- package/gs/unique/index.ts +7 -1
- package/package.json +4 -2
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -926
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -38
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1361
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
|
@@ -242,6 +242,87 @@ func TestSemanticModelRecordsInterfaceAssertionAndNilFacts(t *testing.T) {
|
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
func TestSemanticModelRejectsInterfaceMethodSignatureMismatch(t *testing.T) {
|
|
246
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
247
|
+
"go.mod": "module example.test/signaturemismatch\n\ngo 1.25.3\n",
|
|
248
|
+
"main.go": strings.Join([]string{
|
|
249
|
+
"package signaturemismatch",
|
|
250
|
+
"type Reader interface { Read() int }",
|
|
251
|
+
"type Impl struct{}",
|
|
252
|
+
"func (Impl) Read() string { return \"bad\" }",
|
|
253
|
+
"",
|
|
254
|
+
}, "\n"),
|
|
255
|
+
})
|
|
256
|
+
graph := loadPackageGraph(t, &CompileRequest{
|
|
257
|
+
Patterns: []string{"."},
|
|
258
|
+
Dir: moduleDir,
|
|
259
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
260
|
+
DependencyMode: DependencyModeRequested,
|
|
261
|
+
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
262
|
+
})
|
|
263
|
+
model := buildSemanticModel(t, graph)
|
|
264
|
+
|
|
265
|
+
if hasInterfaceImplementation(model, "Impl", "Reader", false) {
|
|
266
|
+
t.Fatalf("unexpected Impl -> Reader implementation: %#v", model.interfaceImplementations)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
func TestSemanticModelAcceptsPromotedInterfaceMethods(t *testing.T) {
|
|
271
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
272
|
+
"go.mod": "module example.test/promoted\n\ngo 1.25.3\n",
|
|
273
|
+
"main.go": strings.Join([]string{
|
|
274
|
+
"package promoted",
|
|
275
|
+
"type Reader interface { Read() int }",
|
|
276
|
+
"type Base struct{}",
|
|
277
|
+
"func (Base) Read() int { return 1 }",
|
|
278
|
+
"type Impl struct { Base }",
|
|
279
|
+
"",
|
|
280
|
+
}, "\n"),
|
|
281
|
+
})
|
|
282
|
+
graph := loadPackageGraph(t, &CompileRequest{
|
|
283
|
+
Patterns: []string{"."},
|
|
284
|
+
Dir: moduleDir,
|
|
285
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
286
|
+
DependencyMode: DependencyModeRequested,
|
|
287
|
+
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
288
|
+
})
|
|
289
|
+
model := buildSemanticModel(t, graph)
|
|
290
|
+
|
|
291
|
+
if !hasInterfaceImplementation(model, "Impl", "Reader", false) {
|
|
292
|
+
t.Fatalf("missing promoted Impl -> Reader implementation: %#v", model.interfaceImplementations)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
func TestSemanticModelKeepsUnexportedInterfaceMethodsPackageScoped(t *testing.T) {
|
|
297
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
298
|
+
"go.mod": "module example.test/unexportediface\n\ngo 1.25.3\n",
|
|
299
|
+
"dep/dep.go": strings.Join([]string{
|
|
300
|
+
"package dep",
|
|
301
|
+
"type private interface { read() int }",
|
|
302
|
+
"",
|
|
303
|
+
}, "\n"),
|
|
304
|
+
"main.go": strings.Join([]string{
|
|
305
|
+
"package unexportediface",
|
|
306
|
+
"import _ \"example.test/unexportediface/dep\"",
|
|
307
|
+
"type Impl struct{}",
|
|
308
|
+
"func (Impl) read() int { return 1 }",
|
|
309
|
+
"",
|
|
310
|
+
}, "\n"),
|
|
311
|
+
})
|
|
312
|
+
graph := loadPackageGraph(t, &CompileRequest{
|
|
313
|
+
Patterns: []string{"."},
|
|
314
|
+
Dir: moduleDir,
|
|
315
|
+
OutputPath: filepath.Join(t.TempDir(), "out"),
|
|
316
|
+
DependencyMode: DependencyModeAll,
|
|
317
|
+
RuntimeEmissionMode: RuntimeEmissionModeEmit,
|
|
318
|
+
})
|
|
319
|
+
model := buildSemanticModel(t, graph)
|
|
320
|
+
|
|
321
|
+
if hasInterfaceImplementation(model, "Impl", "private", false) {
|
|
322
|
+
t.Fatalf("unexpected cross-package unexported implementation: %#v", model.interfaceImplementations)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
245
326
|
func TestSemanticModelColorsAsyncFunctionsAndOverrides(t *testing.T) {
|
|
246
327
|
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
247
328
|
"go.mod": "module example.test/async\n\ngo 1.25.3\n",
|
|
@@ -356,7 +437,7 @@ func TestSemanticModelPropagatesAsyncToOverrideInterfaceMethods(t *testing.T) {
|
|
|
356
437
|
if implementation.typ != nil && implementation.typ.Obj().Name() == "asyncWriter" &&
|
|
357
438
|
implementation.iface != nil && implementation.iface.Obj().Pkg().Path() == "io" &&
|
|
358
439
|
implementation.iface.Obj().Name() == "Writer" &&
|
|
359
|
-
implementation.pointer
|
|
440
|
+
implementation.pointer {
|
|
360
441
|
found = true
|
|
361
442
|
break
|
|
362
443
|
}
|
package/compiler/service.go
CHANGED
|
@@ -14,6 +14,7 @@ type CompileService struct {
|
|
|
14
14
|
emitterOwner *TypeScriptEmitOwner
|
|
15
15
|
runtimeOwner *RuntimeContractOwner
|
|
16
16
|
overrideOwner *OverrideRegistryOwner
|
|
17
|
+
parityOwner *OverrideParityVerifier
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
// NewCompileService creates a compile service with every pipeline owner.
|
|
@@ -28,6 +29,7 @@ func NewCompileService(overrideDirs ...string) *CompileService {
|
|
|
28
29
|
emitterOwner: NewTypeScriptEmitOwner(runtimeOwner),
|
|
29
30
|
runtimeOwner: runtimeOwner,
|
|
30
31
|
overrideOwner: overrideOwner,
|
|
32
|
+
parityOwner: NewOverrideParityVerifier(),
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
|
|
@@ -96,6 +98,19 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
|
|
|
96
98
|
return result, NewCompileError(diagnostics)
|
|
97
99
|
}
|
|
98
100
|
|
|
101
|
+
overrideFacts, factsDiagnostics := s.overrideOwner.Facts(ctx)
|
|
102
|
+
diagnostics = append(diagnostics, factsDiagnostics...)
|
|
103
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
104
|
+
result.Diagnostics = diagnostics
|
|
105
|
+
return result, NewCompileError(diagnostics)
|
|
106
|
+
}
|
|
107
|
+
parityDiagnostics := s.parityOwner.Verify(ctx, graph, overrideFacts)
|
|
108
|
+
diagnostics = append(diagnostics, parityDiagnostics...)
|
|
109
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
110
|
+
result.Diagnostics = diagnostics
|
|
111
|
+
return result, NewCompileError(diagnostics)
|
|
112
|
+
}
|
|
113
|
+
|
|
99
114
|
semanticModel, semanticDiagnostics := s.semanticOwner.Build(ctx, graph)
|
|
100
115
|
diagnostics = append(diagnostics, semanticDiagnostics...)
|
|
101
116
|
if diagnosticsHaveErrors(diagnostics) {
|
|
@@ -110,7 +125,12 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
|
|
|
110
125
|
return result, NewCompileError(diagnostics)
|
|
111
126
|
}
|
|
112
127
|
|
|
113
|
-
loweredProgram, loweringDiagnostics := s.loweringOwner.Build(ctx, semanticModel
|
|
128
|
+
loweredProgram, loweringDiagnostics := s.loweringOwner.Build(ctx, semanticModel, LoweringOptions{
|
|
129
|
+
SourceRoot: protobufTypeScriptBindingRoot(req.Dir),
|
|
130
|
+
DisplayRoot: req.Dir,
|
|
131
|
+
OutputPath: req.OutputPath,
|
|
132
|
+
ProtobufTypeScriptBinding: req.ProtobufTypeScriptBinding,
|
|
133
|
+
})
|
|
114
134
|
diagnostics = append(diagnostics, loweringDiagnostics...)
|
|
115
135
|
if diagnosticsHaveErrors(diagnostics) {
|
|
116
136
|
result.Diagnostics = diagnostics
|
|
@@ -911,6 +911,49 @@ func TestCompilePackagesAnnotatesNewPointerShortDecls(t *testing.T) {
|
|
|
911
911
|
}
|
|
912
912
|
}
|
|
913
913
|
|
|
914
|
+
func TestCompilePackagesAnnotatesNewArrayPointerShortDecls(t *testing.T) {
|
|
915
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
916
|
+
"go.mod": "module example.test/newarrayptrdecl\n\ngo 1.25.3\n",
|
|
917
|
+
"main.go": strings.Join([]string{
|
|
918
|
+
"package main",
|
|
919
|
+
"func use(*[32]byte) {}",
|
|
920
|
+
"func main() {",
|
|
921
|
+
" buf := new([32]byte)",
|
|
922
|
+
" use(buf)",
|
|
923
|
+
" if true {",
|
|
924
|
+
" buf = nil",
|
|
925
|
+
" }",
|
|
926
|
+
" use(buf)",
|
|
927
|
+
"}",
|
|
928
|
+
"",
|
|
929
|
+
}, "\n"),
|
|
930
|
+
})
|
|
931
|
+
outputDir := filepath.Join(t.TempDir(), "output")
|
|
932
|
+
comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir}, nil, nil)
|
|
933
|
+
if err != nil {
|
|
934
|
+
t.Fatal(err.Error())
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
|
|
938
|
+
t.Fatal(err.Error())
|
|
939
|
+
}
|
|
940
|
+
outputFile := filepath.Join(outputDir, "@goscript", "example.test", "newarrayptrdecl", "main.gs.ts")
|
|
941
|
+
content, err := os.ReadFile(outputFile)
|
|
942
|
+
if err != nil {
|
|
943
|
+
t.Fatal(err.Error())
|
|
944
|
+
}
|
|
945
|
+
text := string(content)
|
|
946
|
+
for _, want := range []string{
|
|
947
|
+
"let buf: $.VarRef<Uint8Array> | null = $.varRef<Uint8Array>(new Uint8Array(32))",
|
|
948
|
+
"buf = null",
|
|
949
|
+
"use(buf)",
|
|
950
|
+
} {
|
|
951
|
+
if !strings.Contains(text, want) {
|
|
952
|
+
t.Fatalf("missing %q in generated output:\n%s", want, text)
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
914
957
|
func TestCompilePackagesEmitsShadowedBuiltinCalls(t *testing.T) {
|
|
915
958
|
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
916
959
|
"go.mod": "module example.test/shadowbuiltin\n\ngo 1.25.3\n",
|
|
@@ -1453,6 +1496,53 @@ func TestCompilePackagesEmitsIndexAddressRefs(t *testing.T) {
|
|
|
1453
1496
|
}
|
|
1454
1497
|
}
|
|
1455
1498
|
|
|
1499
|
+
func TestCompilePackagesLowersUnsafeBytePointerArithmetic(t *testing.T) {
|
|
1500
|
+
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
1501
|
+
"go.mod": "module example.test/unsafeaddr\n\ngo 1.25.3\n",
|
|
1502
|
+
"main.go": strings.Join([]string{
|
|
1503
|
+
"package main",
|
|
1504
|
+
"import \"unsafe\"",
|
|
1505
|
+
"func Set(bits []uint64, idx uint64, mask []uint8) uint8 {",
|
|
1506
|
+
" ptr := unsafe.Pointer(uintptr(unsafe.Pointer(&bits[idx>>6])) + uintptr((idx%64)>>3))",
|
|
1507
|
+
" *(*uint8)(ptr) |= mask[idx%8]",
|
|
1508
|
+
" return *(*uint8)(ptr)",
|
|
1509
|
+
"}",
|
|
1510
|
+
"func CopyBlock(dst []byte, words *[16]uint32) {",
|
|
1511
|
+
" *(*[64]byte)(unsafe.Pointer(&dst[0])) = *(*[64]byte)(unsafe.Pointer(&words[0]))",
|
|
1512
|
+
"}",
|
|
1513
|
+
"",
|
|
1514
|
+
}, "\n"),
|
|
1515
|
+
})
|
|
1516
|
+
outputDir := filepath.Join(t.TempDir(), "output")
|
|
1517
|
+
comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir}, nil, nil)
|
|
1518
|
+
if err != nil {
|
|
1519
|
+
t.Fatal(err.Error())
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
_, err = comp.CompilePackages(context.Background(), ".")
|
|
1523
|
+
if err != nil {
|
|
1524
|
+
t.Fatal(err.Error())
|
|
1525
|
+
}
|
|
1526
|
+
outputFile := filepath.Join(outputDir, "@goscript", "example.test", "unsafeaddr", "main.gs.ts")
|
|
1527
|
+
content, err := os.ReadFile(outputFile)
|
|
1528
|
+
if err != nil {
|
|
1529
|
+
t.Fatal(err.Error())
|
|
1530
|
+
}
|
|
1531
|
+
text := string(content)
|
|
1532
|
+
if !strings.Contains(text, "$.indexByteAddress(bits!, $.uint64Shr(idx, 6), 8)") {
|
|
1533
|
+
t.Fatalf("missing byte-addressed unsafe pointer root:\n%s", text)
|
|
1534
|
+
}
|
|
1535
|
+
if !strings.Contains(text, "$.unsafePointerRef<number>(ptr).value =") {
|
|
1536
|
+
t.Fatalf("missing unsafe pointer storage ref:\n%s", text)
|
|
1537
|
+
}
|
|
1538
|
+
if !strings.Contains(text, "return $.uint($.unsafePointerRef<number>(ptr).value, 8)") {
|
|
1539
|
+
t.Fatalf("missing unsafe pointer value ref:\n%s", text)
|
|
1540
|
+
}
|
|
1541
|
+
if !strings.Contains(text, "$.arrayPointerFromIndexRef<number>($.indexRef($.pointerValue<number[]>(words), 0), 64, 4, 1)") {
|
|
1542
|
+
t.Fatalf("missing byte-view array pointer conversion:\n%s", text)
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1456
1546
|
func TestCompilePackagesEmitsStructMethodsAndPointerAssertions(t *testing.T) {
|
|
1457
1547
|
moduleDir := writePackageGraphFixture(t, map[string]string{
|
|
1458
1548
|
"go.mod": "module example.test/structs\n\ngo 1.25.3\n",
|
|
@@ -1516,8 +1606,8 @@ func TestCompilePackagesEmitsStructMethodsAndPointerAssertions(t *testing.T) {
|
|
|
1516
1606
|
"Counter.prototype.Set.call(pointer, 2)",
|
|
1517
1607
|
"Counter.prototype.Set.call(NewCounter(), 5)",
|
|
1518
1608
|
"let [, ok] = $.typeAssertTuple<Counter | $.VarRef<Counter> | null>(iface, { kind: $.TypeKind.Pointer, elemType: \"main.Counter\" })",
|
|
1519
|
-
"\"Value\":
|
|
1520
|
-
"\"ID\": { kind: $.TypeKind.Basic, name: \"int32\", typeName: \"main.ObjectID\" }",
|
|
1609
|
+
"{ name: \"Value\", key: \"Value\", type: { kind: $.TypeKind.Basic, name: \"int\" }, tag: \"json:\\\"value\\\"\", index: [0], offset: 0, exported: true }",
|
|
1610
|
+
"{ name: \"ID\", key: \"ID\", type: { kind: $.TypeKind.Basic, name: \"int32\", typeName: \"main.ObjectID\" }, index: [1], offset: 8, exported: true }",
|
|
1521
1611
|
} {
|
|
1522
1612
|
if !strings.Contains(text, want) {
|
|
1523
1613
|
t.Fatalf("missing %q in generated output:\n%s", want, text)
|
|
@@ -2345,10 +2435,13 @@ func TestCompilePackagesEmitsInterfacesMethodValuesTypeSwitchesAndFunctionAssert
|
|
|
2345
2435
|
"Read(): string",
|
|
2346
2436
|
"Close(): string",
|
|
2347
2437
|
"$.registerInterfaceType(\n\t\"main.ReadCloser\"",
|
|
2438
|
+
"{ name: \"Close\", args: [], returns: [{ name: \"_r0\", type: { kind: $.TypeKind.Basic, name: \"string\" } }] }]\n);",
|
|
2348
2439
|
"((__receiver) => () => __receiver.Inc())($.pointerValue<Counter>(counter))",
|
|
2349
|
-
"$.namedFunction(greet, \"main.Greeter\"
|
|
2440
|
+
"$.namedFunction(greet, \"main.Greeter\", ({ kind: $.TypeKind.Function, name: \"main.Greeter\"",
|
|
2441
|
+
"params: [{ kind: $.TypeKind.Basic, name: \"string\" }]",
|
|
2442
|
+
"results: [{ kind: $.TypeKind.Basic, name: \"string\" }]",
|
|
2350
2443
|
"$.interfaceValue<any>(null, \"*struct{Name string}\")",
|
|
2351
|
-
"elemType: { kind: $.TypeKind.Struct, methods: [], fields: {\"Name\": { kind: $.TypeKind.Basic, name: \"string\" }
|
|
2444
|
+
"elemType: { kind: $.TypeKind.Struct, methods: [], fields: [{ name: \"Name\", key: \"Name\", type: { kind: $.TypeKind.Basic, name: \"string\" }",
|
|
2352
2445
|
"let fn = __goscriptTuple",
|
|
2353
2446
|
"switch (true)",
|
|
2354
2447
|
"case $.typeAssert<Exclude<ReadCloser, null>>(__goscriptTypeSwitchValue, \"main.ReadCloser\").ok",
|
|
@@ -2612,9 +2705,9 @@ func TestCompilePackagesEmitsGenericMethodsAliasesAndDictionaries(t *testing.T)
|
|
|
2612
2705
|
"$.mapSet(seen, 1, {})",
|
|
2613
2706
|
"$.genericZero(__typeArgs, \"T\", null)",
|
|
2614
2707
|
"$.callGenericMethod(__typeArgs, \"T\", \"String\", v)",
|
|
2615
|
-
"ZeroValue({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)} }})",
|
|
2616
|
-
"CallString({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)} }}, zero)",
|
|
2617
|
-
"Sum({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)} }}, null)",
|
|
2708
|
+
"ZeroValue({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)}, methodSignatures: [{ name: \"String\", args: [], returns: [{ name: \"_r0\", type: { kind: $.TypeKind.Basic, name: \"string\" } }] }] }})",
|
|
2709
|
+
"CallString({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)}, methodSignatures: [{ name: \"String\", args: [], returns: [{ name: \"_r0\", type: { kind: $.TypeKind.Basic, name: \"string\" } }] }] }}, zero)",
|
|
2710
|
+
"Sum({T: { type: { kind: $.TypeKind.Basic, name: \"int\", typeName: \"main.MyInt\" }, zero: () => 0, methods: {String: (receiver: any, ...args: any[]) => (MyInt_String as any)(($.isVarRef(receiver) ? receiver.value : receiver), ...args)}, methodSignatures: [{ name: \"String\", args: [], returns: [{ name: \"_r0\", type: { kind: $.TypeKind.Basic, name: \"string\" } }] }] }}, null)",
|
|
2618
2711
|
} {
|
|
2619
2712
|
if !strings.Contains(text, want) {
|
|
2620
2713
|
t.Fatalf("missing %q in generated output:\n%s", want, text)
|
|
@@ -2761,7 +2854,7 @@ func TestCompilePackagesEmitsRecursiveFunctionTypeInfo(t *testing.T) {
|
|
|
2761
2854
|
text := string(content)
|
|
2762
2855
|
for _, want := range []string{
|
|
2763
2856
|
"export type Handler = ((_p0: ((_p0: Handler | null) => Handler | null | globalThis.Promise<Handler | null>) | null) => Handler | null | globalThis.Promise<Handler | null>) | null",
|
|
2764
|
-
"\"Next\": ({ kind: $.TypeKind.Function, name: \"main.Handler\"",
|
|
2857
|
+
"{ name: \"Next\", key: \"Next\", type: ({ kind: $.TypeKind.Function, name: \"main.Handler\"",
|
|
2765
2858
|
"params: [{ kind: $.TypeKind.Function, params: [], results: [] }]",
|
|
2766
2859
|
"results: [{ kind: $.TypeKind.Function, params: [], results: [] }]",
|
|
2767
2860
|
} {
|
|
@@ -4127,6 +4220,12 @@ func TestCompilePackagesLowersSwitchesAndFunctionValueCalls(t *testing.T) {
|
|
|
4127
4220
|
" if value > 0 {",
|
|
4128
4221
|
" goto Again",
|
|
4129
4222
|
" }",
|
|
4223
|
+
"Drive:",
|
|
4224
|
+
" window := value + 1",
|
|
4225
|
+
" if window < 0 {",
|
|
4226
|
+
" goto Drive",
|
|
4227
|
+
" }",
|
|
4228
|
+
" println(window)",
|
|
4130
4229
|
" release := func() { println(\"release\") }",
|
|
4131
4230
|
" rel := &release",
|
|
4132
4231
|
" (*rel)()",
|
|
@@ -4163,6 +4262,9 @@ func TestCompilePackagesLowersSwitchesAndFunctionValueCalls(t *testing.T) {
|
|
|
4163
4262
|
"break Block",
|
|
4164
4263
|
"Again: while (true)",
|
|
4165
4264
|
"continue Again",
|
|
4265
|
+
"Drive: while (true)",
|
|
4266
|
+
"var window = value + 1",
|
|
4267
|
+
"$.println(window)",
|
|
4166
4268
|
"($.pointerValue<(() => void) | null>(rel))!()",
|
|
4167
4269
|
"$.functionValue((): void => {\n\t\tusing __defer = new $.DisposableStack()",
|
|
4168
4270
|
"__defer.defer(() => { $.println(\"wrapped deferred\") })",
|
|
@@ -4299,10 +4401,15 @@ func TestCompilePackagesLowersUnaryBitwiseComplement(t *testing.T) {
|
|
|
4299
4401
|
"main.go": strings.Join([]string{
|
|
4300
4402
|
"package main",
|
|
4301
4403
|
"var value = 1",
|
|
4404
|
+
"var wide uint64 = 1",
|
|
4405
|
+
"var signed int64 = 1",
|
|
4406
|
+
"func invert(crc uint64) uint64 {",
|
|
4407
|
+
" return ^crc",
|
|
4408
|
+
"}",
|
|
4302
4409
|
"func main() {",
|
|
4303
4410
|
" mask := 7",
|
|
4304
4411
|
" mask &^= 3",
|
|
4305
|
-
" println(^value, value &^ 3, mask, 0700)",
|
|
4412
|
+
" println(^value, ^wide, ^signed, invert(wide), value &^ 3, mask, 0700)",
|
|
4306
4413
|
"}",
|
|
4307
4414
|
"",
|
|
4308
4415
|
}, "\n"),
|
|
@@ -4323,8 +4430,9 @@ func TestCompilePackagesLowersUnaryBitwiseComplement(t *testing.T) {
|
|
|
4323
4430
|
}
|
|
4324
4431
|
text := string(content)
|
|
4325
4432
|
for _, want := range []string{
|
|
4433
|
+
"return $.uint($.uint64Xor(crc, -1n), 64)",
|
|
4326
4434
|
"mask = mask & ~((3))",
|
|
4327
|
-
"$.println(
|
|
4435
|
+
"$.println($.int64Xor(value, -1n), $.uint($.uint64Xor(wide, -1n), 64), $.int($.int64Xor(signed, -1n)), $.uint(invert($.uint(wide, 64)), 64), value & ~(3), mask, 0o700)",
|
|
4328
4436
|
} {
|
|
4329
4437
|
if !strings.Contains(text, want) {
|
|
4330
4438
|
t.Fatalf("missing %q in generated output:\n%s", want, text)
|
|
@@ -134,6 +134,7 @@ func (o *TypeScriptEmitOwner) EmitToMemory(
|
|
|
134
134
|
|
|
135
135
|
func (o *TypeScriptEmitOwner) renderLoweredFile(pkg *loweredPackage, file *loweredFile) string {
|
|
136
136
|
var b strings.Builder
|
|
137
|
+
b.Grow(estimateLoweredFileSize(file))
|
|
137
138
|
if file.sourcePath != "" {
|
|
138
139
|
b.WriteString("// Generated file based on ")
|
|
139
140
|
b.WriteString(filepath.Base(file.sourcePath))
|
|
@@ -219,6 +220,104 @@ func (o *TypeScriptEmitOwner) renderLoweredFile(pkg *loweredPackage, file *lower
|
|
|
219
220
|
return b.String()
|
|
220
221
|
}
|
|
221
222
|
|
|
223
|
+
func estimateLoweredFileSize(file *loweredFile) int {
|
|
224
|
+
if file == nil {
|
|
225
|
+
return 0
|
|
226
|
+
}
|
|
227
|
+
size := 128 + len(file.imports)*96 + len(file.decls)*32
|
|
228
|
+
for _, imp := range file.imports {
|
|
229
|
+
size += len(imp.alias) + len(imp.source)
|
|
230
|
+
}
|
|
231
|
+
for _, decl := range file.decls {
|
|
232
|
+
size += len(decl.code)
|
|
233
|
+
if decl.function != nil {
|
|
234
|
+
size += estimateLoweredFunctionSize(decl.function)
|
|
235
|
+
}
|
|
236
|
+
if decl.structType != nil {
|
|
237
|
+
size += estimateLoweredStructSize(decl.structType)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return size
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
func estimateLoweredStructSize(structType *loweredStruct) int {
|
|
244
|
+
if structType == nil {
|
|
245
|
+
return 0
|
|
246
|
+
}
|
|
247
|
+
size := 256 + len(structType.name) + len(structType.typeName) + len(structType.fields)*128
|
|
248
|
+
for _, field := range structType.fields {
|
|
249
|
+
size += len(field.name) + len(field.runtimeName) + len(field.typ) + len(field.zero) + len(field.runtimeType) +
|
|
250
|
+
len(field.doc) + len(field.tag)
|
|
251
|
+
}
|
|
252
|
+
for idx := range structType.methods {
|
|
253
|
+
size += estimateLoweredFunctionSize(&structType.methods[idx])
|
|
254
|
+
}
|
|
255
|
+
return size
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
func estimateLoweredFunctionSize(fn *loweredFunction) int {
|
|
259
|
+
if fn == nil {
|
|
260
|
+
return 0
|
|
261
|
+
}
|
|
262
|
+
size := 192 + len(fn.name) + len(fn.result) + len(fn.receiverAlias) + len(fn.receiverType) + len(fn.receiverValue)
|
|
263
|
+
for _, typeParam := range fn.typeParams {
|
|
264
|
+
size += len(typeParam) + 2
|
|
265
|
+
}
|
|
266
|
+
for _, param := range fn.params {
|
|
267
|
+
size += len(param.name) + len(param.typ) + 4
|
|
268
|
+
}
|
|
269
|
+
for _, result := range fn.namedResults {
|
|
270
|
+
size += len(result.name) + len(result.typ) + len(result.zero) + len(result.returnExpr) + 16
|
|
271
|
+
}
|
|
272
|
+
size += estimateLoweredStmtsSize(fn.paramBindings)
|
|
273
|
+
size += estimateLoweredStmtsSize(fn.body)
|
|
274
|
+
return size
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
func estimateLoweredStmtsSize(stmts []loweredStmt) int {
|
|
278
|
+
size := len(stmts) * 24
|
|
279
|
+
for _, stmt := range stmts {
|
|
280
|
+
size += len(stmt.text) + len(stmt.leading)*16
|
|
281
|
+
for _, line := range stmt.leading {
|
|
282
|
+
size += len(line)
|
|
283
|
+
}
|
|
284
|
+
size += estimateLoweredStmtsSize(stmt.children)
|
|
285
|
+
size += estimateLoweredStmtsSize(stmt.elseBody)
|
|
286
|
+
if stmt.rangeFunc != nil {
|
|
287
|
+
size += len(stmt.rangeFunc.value) + len(stmt.rangeFunc.params)*16 + estimateLoweredStmtsSize(stmt.rangeFunc.body)
|
|
288
|
+
}
|
|
289
|
+
if stmt.switchStmt != nil {
|
|
290
|
+
size += len(stmt.switchStmt.value)
|
|
291
|
+
for _, switchCase := range stmt.switchStmt.cases {
|
|
292
|
+
size += len(switchCase.values)*16 + estimateLoweredStmtsSize(switchCase.body)
|
|
293
|
+
for _, value := range switchCase.values {
|
|
294
|
+
size += len(value)
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if stmt.selectStmt != nil {
|
|
299
|
+
size += len(stmt.selectStmt.hasReturn) + len(stmt.selectStmt.value) + len(stmt.selectStmt.result) + len(stmt.selectStmt.resultType)
|
|
300
|
+
for _, selectCase := range stmt.selectStmt.cases {
|
|
301
|
+
size += len(selectCase.channel) + len(selectCase.value) + estimateLoweredStmtsSize(selectCase.prelude) +
|
|
302
|
+
estimateLoweredStmtsSize(selectCase.body)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if stmt.typeSwitch != nil {
|
|
306
|
+
size += len(stmt.typeSwitch.value) + len(stmt.typeSwitch.varName) + estimateLoweredStmtsSize(stmt.typeSwitch.defaultBody)
|
|
307
|
+
for _, switchCase := range stmt.typeSwitch.cases {
|
|
308
|
+
for _, typ := range switchCase.types {
|
|
309
|
+
size += len(typ)
|
|
310
|
+
}
|
|
311
|
+
for _, typ := range switchCase.tsTypes {
|
|
312
|
+
size += len(typ)
|
|
313
|
+
}
|
|
314
|
+
size += estimateLoweredStmtsSize(switchCase.body)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return size
|
|
319
|
+
}
|
|
320
|
+
|
|
222
321
|
func sortedStructDecls(decls []loweredDecl) []loweredDecl {
|
|
223
322
|
structs := make([]loweredDecl, 0)
|
|
224
323
|
names := make(map[string]bool)
|
|
@@ -421,29 +520,42 @@ func renderStruct(b *strings.Builder, structType *loweredStruct, runtimeOwner *R
|
|
|
421
520
|
if idx != 0 {
|
|
422
521
|
b.WriteString(", ")
|
|
423
522
|
}
|
|
424
|
-
|
|
425
|
-
if method.runtimeName != "" {
|
|
426
|
-
methodName = method.runtimeName
|
|
427
|
-
}
|
|
428
|
-
b.WriteString("{ name: ")
|
|
429
|
-
b.WriteString(strconvQuote(methodName))
|
|
430
|
-
b.WriteString(", args: [], returns: [] }")
|
|
523
|
+
b.WriteString(runtimeMethodSignatureExpr(method))
|
|
431
524
|
}
|
|
432
525
|
b.WriteString("],\n\t\t")
|
|
433
526
|
b.WriteString(structType.name)
|
|
434
|
-
b.WriteString(",\n\t\t
|
|
527
|
+
b.WriteString(",\n\t\t[")
|
|
435
528
|
for idx, field := range structType.fields {
|
|
436
529
|
if idx != 0 {
|
|
437
530
|
b.WriteString(", ")
|
|
438
531
|
}
|
|
439
|
-
b.WriteString(
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
532
|
+
b.WriteString(runtimeStructFieldInfoExpr(
|
|
533
|
+
field.runtimeType,
|
|
534
|
+
field.name,
|
|
535
|
+
field.runtimeName,
|
|
536
|
+
field.tag,
|
|
537
|
+
field.pkgPath,
|
|
538
|
+
field.anonymous,
|
|
539
|
+
field.index,
|
|
540
|
+
field.offset,
|
|
541
|
+
field.exported,
|
|
542
|
+
))
|
|
543
|
+
}
|
|
544
|
+
b.WriteString("]\n\t)\n")
|
|
444
545
|
b.WriteString("}\n")
|
|
445
546
|
}
|
|
446
547
|
|
|
548
|
+
func runtimeMethodSignatureExpr(method loweredFunction) string {
|
|
549
|
+
if method.runtimeSignature != "" {
|
|
550
|
+
return method.runtimeSignature
|
|
551
|
+
}
|
|
552
|
+
methodName := method.name
|
|
553
|
+
if method.runtimeName != "" {
|
|
554
|
+
methodName = method.runtimeName
|
|
555
|
+
}
|
|
556
|
+
return "{ name: " + strconvQuote(methodName) + ", args: [], returns: [] }"
|
|
557
|
+
}
|
|
558
|
+
|
|
447
559
|
func writeLineComment(b *strings.Builder, indent string, comment string) {
|
|
448
560
|
comment = strings.TrimSpace(comment)
|
|
449
561
|
if comment == "" {
|
|
@@ -1158,6 +1270,9 @@ func renderIndex(pkg *loweredPackage) string {
|
|
|
1158
1270
|
if file.sideEffect {
|
|
1159
1271
|
lines = append(lines, "import \"./"+file.outputName+"\"")
|
|
1160
1272
|
}
|
|
1273
|
+
if file.exportAll {
|
|
1274
|
+
lines = append(lines, "export * from \"./"+file.outputName+"\"")
|
|
1275
|
+
}
|
|
1161
1276
|
exports := slices.Clone(file.exports)
|
|
1162
1277
|
slices.Sort(exports)
|
|
1163
1278
|
if len(exports) != 0 {
|
|
@@ -49,7 +49,8 @@ func TestCompileSourceReportsParseErrors(t *testing.T) {
|
|
|
49
49
|
if err == nil {
|
|
50
50
|
t.Fatal("expected compile error")
|
|
51
51
|
}
|
|
52
|
-
requireCompileDiagnostic(t, err, "goscript/wasm:parse")
|
|
52
|
+
diag := requireCompileDiagnostic(t, err, "goscript/wasm:parse")
|
|
53
|
+
requireDiagnosticPosition(t, diag, "main.go", 2, 12)
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
func TestCompileSourceReportsUnsupportedImports(t *testing.T) {
|
|
@@ -57,10 +58,27 @@ func TestCompileSourceReportsUnsupportedImports(t *testing.T) {
|
|
|
57
58
|
if err == nil {
|
|
58
59
|
t.Fatal("expected compile error")
|
|
59
60
|
}
|
|
60
|
-
requireCompileDiagnostic(t, err, "goscript/wasm:imports-unsupported")
|
|
61
|
+
diag := requireCompileDiagnostic(t, err, "goscript/wasm:imports-unsupported")
|
|
62
|
+
requireDiagnosticPosition(t, diag, "main.go", 3, 8)
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
func
|
|
65
|
+
func TestCompileSourceReportsTypecheckPositions(t *testing.T) {
|
|
66
|
+
_, err := CompileSource(strings.Join([]string{
|
|
67
|
+
"package main",
|
|
68
|
+
"",
|
|
69
|
+
"func main() {",
|
|
70
|
+
" missing()",
|
|
71
|
+
"}",
|
|
72
|
+
"",
|
|
73
|
+
}, "\n"), "main")
|
|
74
|
+
if err == nil {
|
|
75
|
+
t.Fatal("expected compile error")
|
|
76
|
+
}
|
|
77
|
+
diag := requireCompileDiagnostic(t, err, "goscript/wasm:typecheck")
|
|
78
|
+
requireDiagnosticPosition(t, diag, "main.go", 4, 5)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
func requireCompileDiagnostic(t *testing.T, err error, code string) compiler.Diagnostic {
|
|
64
82
|
t.Helper()
|
|
65
83
|
|
|
66
84
|
var compileErr *compiler.CompileError
|
|
@@ -72,8 +90,23 @@ func requireCompileDiagnostic(t *testing.T, err error, code string) {
|
|
|
72
90
|
if diag.Severity != compiler.DiagnosticSeverityError {
|
|
73
91
|
t.Fatalf("expected error severity, got %s", diag.Severity)
|
|
74
92
|
}
|
|
75
|
-
return
|
|
93
|
+
return diag
|
|
76
94
|
}
|
|
77
95
|
}
|
|
78
96
|
t.Fatalf("missing diagnostic %q in %#v", code, compileErr.Diagnostics)
|
|
97
|
+
return compiler.Diagnostic{}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
func requireDiagnosticPosition(t *testing.T, diag compiler.Diagnostic, displayFile string, line int, column int) {
|
|
101
|
+
t.Helper()
|
|
102
|
+
|
|
103
|
+
if diag.Position == nil {
|
|
104
|
+
t.Fatalf("expected position in %#v", diag)
|
|
105
|
+
}
|
|
106
|
+
if diag.Position.DisplayFile != displayFile {
|
|
107
|
+
t.Fatalf("DisplayFile = %q, want %q", diag.Position.DisplayFile, displayFile)
|
|
108
|
+
}
|
|
109
|
+
if diag.Position.Line != line || diag.Position.Column != column {
|
|
110
|
+
t.Fatalf("position = %d:%d, want %d:%d", diag.Position.Line, diag.Position.Column, line, column)
|
|
111
|
+
}
|
|
79
112
|
}
|