diff --git a/CHANGELOG.md b/CHANGELOG.md index 163d8ed8..ba38d489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added +- [#128](https://github.com/ydnar/wasm-tools-go/pull/128): implemented `String` method for `enum` types ([@rajatjindal](https://github.com/rajatjindal)). + +### Fixed +- [#130](https://github.com/ydnar/wasm-tools-go/issues/130): anonymous `tuple` types now correctly have exported Go struct fields. +- [#129](https://github.com/ydnar/wasm-tools-go/issues/129): correctly handle zero-length `tuple` and `record` types, represented as `struct{}`. + ## [v0.1.2] — 2024-07-05 ### Added diff --git a/testdata/example/non-flat-params.wit b/testdata/example/non-flat-params.wit index 74d62123..a22a8ba6 100644 --- a/testdata/example/non-flat-params.wit +++ b/testdata/example/non-flat-params.wit @@ -1,12 +1,17 @@ package example:non-flat-params; interface corner-case { + type t0 = tuple<>; type t4 = tuple; type t16 = tuple; type t32 = tuple; f: func(); + f0-void: func(t: tuple<>); + f0-u32: func(t: tuple<>) -> u32; + f0-t0: func(t: tuple<>) -> t0; + f4-void: func(t: t4); f4-u32: func(t: t4) -> u32; f4-t4: func(t: t4) -> t4; diff --git a/testdata/example/non-flat-params.wit.json b/testdata/example/non-flat-params.wit.json index 47bfb522..81f89c46 100644 --- a/testdata/example/non-flat-params.wit.json +++ b/testdata/example/non-flat-params.wit.json @@ -23,10 +23,11 @@ { "name": "corner-case", "types": { - "t4": 0, - "t16": 1, - "t32": 2, - "wind": 3 + "t0": 0, + "t4": 1, + "t16": 2, + "t32": 3, + "wind": 4 }, "functions": { "f": { @@ -35,13 +36,54 @@ "params": [], "results": [] }, + "f0-void": { + "name": "f0-void", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 5 + } + ], + "results": [] + }, + "f0-u32": { + "name": "f0-u32", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 5 + } + ], + "results": [ + { + "type": "u32" + } + ] + }, + "f0-t0": { + "name": "f0-t0", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 5 + } + ], + "results": [ + { + "type": 0 + } + ] + }, "f4-void": { "name": "f4-void", "kind": "freestanding", "params": [ { "name": "t", - "type": 0 + "type": 1 } ], "results": [] @@ -52,7 +94,7 @@ "params": [ { "name": "t", - "type": 0 + "type": 1 } ], "results": [ @@ -67,12 +109,12 @@ "params": [ { "name": "t", - "type": 0 + "type": 1 } ], "results": [ { - "type": 0 + "type": 1 } ] }, @@ -82,7 +124,7 @@ "params": [ { "name": "t", - "type": 1 + "type": 2 } ], "results": [] @@ -93,7 +135,7 @@ "params": [ { "name": "t", - "type": 1 + "type": 2 } ], "results": [ @@ -108,12 +150,12 @@ "params": [ { "name": "t", - "type": 1 + "type": 2 } ], "results": [ { - "type": 1 + "type": 2 } ] }, @@ -123,7 +165,7 @@ "params": [ { "name": "t", - "type": 2 + "type": 3 } ], "results": [] @@ -134,7 +176,7 @@ "params": [ { "name": "t", - "type": 2 + "type": 3 } ], "results": [ @@ -149,12 +191,12 @@ "params": [ { "name": "t", - "type": 2 + "type": 3 } ], "results": [ { - "type": 2 + "type": 3 } ] }, @@ -766,12 +808,12 @@ "[method]wind.f": { "name": "[method]wind.f", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 } ], "results": [] @@ -779,16 +821,16 @@ "[method]wind.f4-void": { "name": "[method]wind.f4-void", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "t", - "type": 0 + "type": 1 } ], "results": [] @@ -796,16 +838,16 @@ "[method]wind.f4-u32": { "name": "[method]wind.f4-u32", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "t", - "type": 0 + "type": 1 } ], "results": [ @@ -817,37 +859,37 @@ "[method]wind.f4-t4": { "name": "[method]wind.f4-t4", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "t", - "type": 0 + "type": 1 } ], "results": [ { - "type": 0 + "type": 1 } ] }, "[method]wind.f16-void": { "name": "[method]wind.f16-void", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "t", - "type": 1 + "type": 2 } ], "results": [] @@ -855,16 +897,16 @@ "[method]wind.f16-u32": { "name": "[method]wind.f16-u32", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "t", - "type": 1 + "type": 2 } ], "results": [ @@ -876,37 +918,37 @@ "[method]wind.f16-t16": { "name": "[method]wind.f16-t16", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "t", - "type": 1 + "type": 2 } ], "results": [ { - "type": 1 + "type": 2 } ] }, "[method]wind.f32-void": { "name": "[method]wind.f32-void", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "t", - "type": 2 + "type": 3 } ], "results": [] @@ -914,16 +956,16 @@ "[method]wind.f32-u32": { "name": "[method]wind.f32-u32", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "t", - "type": 2 + "type": 3 } ], "results": [ @@ -935,33 +977,33 @@ "[method]wind.f32-t32": { "name": "[method]wind.f32-t32", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "t", - "type": 2 + "type": 3 } ], "results": [ { - "type": 2 + "type": 3 } ] }, "[method]wind.u16-void": { "name": "[method]wind.u16-void", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "a", @@ -1033,12 +1075,12 @@ "[method]wind.u16-u8": { "name": "[method]wind.u16-u8", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "a", @@ -1114,12 +1156,12 @@ "[method]wind.u16-u8-u8": { "name": "[method]wind.u16-u8-u8", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "a", @@ -1200,12 +1242,12 @@ "[method]wind.u16-u32-u64": { "name": "[method]wind.u16-u32-u64", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "a", @@ -1286,12 +1328,12 @@ "[method]wind.u16-x17-u8": { "name": "[method]wind.u16-x17-u8", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "a", @@ -1432,12 +1474,12 @@ "[method]wind.u17-void": { "name": "[method]wind.u17-void", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "a", @@ -1513,12 +1555,12 @@ "[method]wind.u17-u8-u8": { "name": "[method]wind.u17-u8-u8", "kind": { - "method": 3 + "method": 4 }, "params": [ { "name": "self", - "type": 4 + "type": 6 }, { "name": "a", @@ -1605,6 +1647,17 @@ } ], "types": [ + { + "name": "t0", + "kind": { + "tuple": { + "types": [] + } + }, + "owner": { + "interface": 0 + } + }, { "name": "t4", "kind": { @@ -1626,10 +1679,10 @@ "kind": { "tuple": { "types": [ - 0, - 0, - 0, - 0 + 1, + 1, + 1, + 1 ] } }, @@ -1642,8 +1695,8 @@ "kind": { "tuple": { "types": [ - 1, - 1 + 2, + 2 ] } }, @@ -1658,11 +1711,20 @@ "interface": 0 } }, + { + "name": null, + "kind": { + "tuple": { + "types": [] + } + }, + "owner": null + }, { "name": null, "kind": { "handle": { - "borrow": 3 + "borrow": 4 } }, "owner": null diff --git a/testdata/example/non-flat-params.wit.json.golden.wit b/testdata/example/non-flat-params.wit.json.golden.wit index b7e434f4..2ec0071b 100644 --- a/testdata/example/non-flat-params.wit.json.golden.wit +++ b/testdata/example/non-flat-params.wit.json.golden.wit @@ -1,6 +1,7 @@ package example:non-flat-params; interface corner-case { + type t0 = tuple<>; type t4 = tuple; type t16 = tuple; type t32 = tuple; @@ -24,6 +25,9 @@ interface corner-case { u17-void: func(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8, g: u8, h: u8, i: u8, j: u8, k: u8, l: u8, m: u8, n: u8, o: u8, p: u8, q: u8); } f: func(); + f0-void: func(t: tuple<>); + f0-u32: func(t: tuple<>) -> u32; + f0-t0: func(t: tuple<>) -> t0; f4-void: func(t: t4); f4-u32: func(t: t4) -> u32; f4-t4: func(t: t4) -> t4; diff --git a/testdata/example/records.wit b/testdata/example/records.wit index d1094752..6d172d11 100644 --- a/testdata/example/records.wit +++ b/testdata/example/records.wit @@ -16,6 +16,10 @@ interface a { } handle: func(r: request) -> response; + + record empty {} + + handle-empty: func(e: empty) -> empty; } world imports { diff --git a/testdata/example/records.wit.json b/testdata/example/records.wit.json index 936ded67..79993526 100644 --- a/testdata/example/records.wit.json +++ b/testdata/example/records.wit.json @@ -25,7 +25,8 @@ "types": { "value": 0, "request": 2, - "response": 3 + "response": 3, + "empty": 4 }, "functions": { "handle": { @@ -42,6 +43,21 @@ "type": 3 } ] + }, + "handle-empty": { + "name": "handle-empty", + "kind": "freestanding", + "params": [ + { + "name": "e", + "type": 4 + } + ], + "results": [ + { + "type": 4 + } + ] } }, "package": 0 @@ -111,6 +127,17 @@ "owner": { "interface": 0 } + }, + { + "name": "empty", + "kind": { + "record": { + "fields": [] + } + }, + "owner": { + "interface": 0 + } } ], "packages": [ diff --git a/testdata/example/records.wit.json.golden.wit b/testdata/example/records.wit.json.golden.wit index 9760c76b..9b103362 100644 --- a/testdata/example/records.wit.json.golden.wit +++ b/testdata/example/records.wit.json.golden.wit @@ -12,7 +12,9 @@ interface a { rating: u32, attributes: list, } + record empty {} handle: func(r: request) -> response; + handle-empty: func(e: empty) -> empty; } world imports { diff --git a/testdata/example/tuples.wit b/testdata/example/tuples.wit index f09f21b1..d2af15db 100644 --- a/testdata/example/tuples.wit +++ b/testdata/example/tuples.wit @@ -12,4 +12,33 @@ interface tuples { type t8 = tuple; type t9 = tuple; type t10 = tuple; + + f0: func(t: t0) -> tuple<>; + f1: func(t: t1) -> tuple; + f2: func(t: t2) -> tuple; + f3: func(t: t3) -> tuple; + f4: func(t: t4) -> tuple; + f5: func(t: t5) -> tuple; + f6: func(t: t6) -> tuple; + f7: func(t: t7) -> tuple; + f8: func(t: t8) -> tuple; + f9: func(t: t9) -> tuple; + f10: func(t: t10) -> tuple; + + g0: func(t: tuple<>) -> tuple<>; + g1: func(t: tuple) -> tuple; + g2: func(t: tuple) -> tuple; + g3: func(t: tuple) -> tuple; + g4: func(t: tuple) -> tuple; + g5: func(t: tuple) -> tuple; + g6: func(t: tuple) -> tuple; + g7: func(t: tuple) -> tuple; + g8: func(t: tuple) -> tuple; + g9: func(t: tuple) -> tuple; + g10: func(t: tuple) -> tuple; +} + +world w { + import tuples; + export tuples; } diff --git a/testdata/example/tuples.wit.json b/testdata/example/tuples.wit.json index b12f2507..07461292 100644 --- a/testdata/example/tuples.wit.json +++ b/testdata/example/tuples.wit.json @@ -1,5 +1,24 @@ { - "worlds": [], + "worlds": [ + { + "name": "w", + "imports": { + "interface-0": { + "interface": { + "id": 0 + } + } + }, + "exports": { + "interface-0": { + "interface": { + "id": 0 + } + } + }, + "package": 0 + } + ], "interfaces": [ { "name": "tuples", @@ -16,7 +35,338 @@ "t9": 9, "t10": 10 }, - "functions": {}, + "functions": { + "f0": { + "name": "f0", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 0 + } + ], + "results": [ + { + "type": 11 + } + ] + }, + "f1": { + "name": "f1", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 1 + } + ], + "results": [ + { + "type": 12 + } + ] + }, + "f2": { + "name": "f2", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 2 + } + ], + "results": [ + { + "type": 13 + } + ] + }, + "f3": { + "name": "f3", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 3 + } + ], + "results": [ + { + "type": 14 + } + ] + }, + "f4": { + "name": "f4", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 4 + } + ], + "results": [ + { + "type": 15 + } + ] + }, + "f5": { + "name": "f5", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 5 + } + ], + "results": [ + { + "type": 16 + } + ] + }, + "f6": { + "name": "f6", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 6 + } + ], + "results": [ + { + "type": 17 + } + ] + }, + "f7": { + "name": "f7", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 7 + } + ], + "results": [ + { + "type": 18 + } + ] + }, + "f8": { + "name": "f8", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 8 + } + ], + "results": [ + { + "type": 19 + } + ] + }, + "f9": { + "name": "f9", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 9 + } + ], + "results": [ + { + "type": 20 + } + ] + }, + "f10": { + "name": "f10", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 10 + } + ], + "results": [ + { + "type": 21 + } + ] + }, + "g0": { + "name": "g0", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 11 + } + ], + "results": [ + { + "type": 11 + } + ] + }, + "g1": { + "name": "g1", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 12 + } + ], + "results": [ + { + "type": 12 + } + ] + }, + "g2": { + "name": "g2", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 13 + } + ], + "results": [ + { + "type": 13 + } + ] + }, + "g3": { + "name": "g3", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 14 + } + ], + "results": [ + { + "type": 14 + } + ] + }, + "g4": { + "name": "g4", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 15 + } + ], + "results": [ + { + "type": 15 + } + ] + }, + "g5": { + "name": "g5", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 16 + } + ], + "results": [ + { + "type": 16 + } + ] + }, + "g6": { + "name": "g6", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 17 + } + ], + "results": [ + { + "type": 17 + } + ] + }, + "g7": { + "name": "g7", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 18 + } + ], + "results": [ + { + "type": 18 + } + ] + }, + "g8": { + "name": "g8", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 19 + } + ], + "results": [ + { + "type": 19 + } + ] + }, + "g9": { + "name": "g9", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 20 + } + ], + "results": [ + { + "type": 20 + } + ] + }, + "g10": { + "name": "g10", + "kind": "freestanding", + "params": [ + { + "name": "t", + "type": 21 + } + ], + "results": [ + { + "type": 21 + } + ] + } + }, "package": 0 } ], @@ -206,6 +556,170 @@ "owner": { "interface": 0 } + }, + { + "name": null, + "kind": { + "tuple": { + "types": [] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string" + ] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string", + "bool" + ] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string", + "bool", + "u8" + ] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string", + "bool", + "u8", + "u16" + ] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string", + "bool", + "u8", + "u16", + "u32" + ] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string", + "bool", + "u8", + "u16", + "u32", + "u64" + ] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string", + "bool", + "u8", + "u16", + "u32", + "u64", + "f32" + ] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string", + "bool", + "u8", + "u16", + "u32", + "u64", + "f32", + "f64" + ] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string", + "bool", + "u8", + "u16", + "u32", + "u64", + "f32", + "f64", + "s8" + ] + } + }, + "owner": null + }, + { + "name": null, + "kind": { + "tuple": { + "types": [ + "string", + "bool", + "u8", + "u16", + "u32", + "u64", + "f32", + "f64", + "s8", + "s16" + ] + } + }, + "owner": null } ], "packages": [ @@ -214,7 +728,9 @@ "interfaces": { "tuples": 0 }, - "worlds": {} + "worlds": { + "w": 0 + } } ] } \ No newline at end of file diff --git a/testdata/example/tuples.wit.json.golden.wit b/testdata/example/tuples.wit.json.golden.wit index f09f21b1..8a8db11f 100644 --- a/testdata/example/tuples.wit.json.golden.wit +++ b/testdata/example/tuples.wit.json.golden.wit @@ -12,4 +12,31 @@ interface tuples { type t8 = tuple; type t9 = tuple; type t10 = tuple; + f0: func(t: t0) -> tuple<>; + f1: func(t: t1) -> tuple; + f2: func(t: t2) -> tuple; + f3: func(t: t3) -> tuple; + f4: func(t: t4) -> tuple; + f5: func(t: t5) -> tuple; + f6: func(t: t6) -> tuple; + f7: func(t: t7) -> tuple; + f8: func(t: t8) -> tuple; + f9: func(t: t9) -> tuple; + f10: func(t: t10) -> tuple; + g0: func(t: tuple<>) -> tuple<>; + g1: func(t: tuple) -> tuple; + g2: func(t: tuple) -> tuple; + g3: func(t: tuple) -> tuple; + g4: func(t: tuple) -> tuple; + g5: func(t: tuple) -> tuple; + g6: func(t: tuple) -> tuple; + g7: func(t: tuple) -> tuple; + g8: func(t: tuple) -> tuple; + g9: func(t: tuple) -> tuple; + g10: func(t: tuple) -> tuple; +} + +world w { + import tuples; + export tuples; } diff --git a/wit/abi.go b/wit/abi.go index 5bb475b2..d8dae5b1 100644 --- a/wit/abi.go +++ b/wit/abi.go @@ -37,8 +37,7 @@ func Discriminant(n int) Type { return U32{} } -// Despecialize [despecializes] k if k implements [Despecializer]. -// Otherwise, it returns k unmodified. +// Despecialize [despecializes] k if k can be despecialized. Otherwise, it returns k unmodified. // See the [canonical ABI documentation] for more information. // // [despecializes]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md#despecialization diff --git a/wit/bindgen/generator.go b/wit/bindgen/generator.go index be6114a9..286e106d 100644 --- a/wit/bindgen/generator.go +++ b/wit/bindgen/generator.go @@ -566,6 +566,23 @@ func (g *generator) declareTypeDef(file *gen.File, dir wit.Direction, t *wit.Typ return decl, nil } +func typeDefOwner(t *wit.TypeDef) wit.Ident { + var id wit.Ident + switch owner := t.Owner.(type) { + case *wit.World: + id = owner.Package.Name + id.Extension = owner.Name + case *wit.Interface: + id = owner.Package.Name + if owner.Name == nil { + id.Extension = "unknown" + } else { + id.Extension = *owner.Name + } + } + return id +} + func declareDirectedName(scope gen.Scope, dir wit.Direction, name string) string { if dir == wit.Exported && scope.HasName(name) { if token.IsExported(name) { @@ -588,31 +605,6 @@ func (g *generator) typeDecl(dir wit.Direction, t *wit.TypeDef) (typeDecl, bool) return decl, ok } -func typeDefOwner(t *wit.TypeDef) wit.Ident { - var id wit.Ident - switch owner := t.Owner.(type) { - case *wit.World: - id = owner.Package.Name - id.Extension = owner.Name - case *wit.Interface: - id = owner.Package.Name - if owner.Name == nil { - id.Extension = "unknown" - } else { - id.Extension = *owner.Name - } - } - return id -} - -// typeDefGoName returns a mangled Go name for t. -func (g *generator) typeDefGoName(dir wit.Direction, t *wit.TypeDef) string { - if decl, ok := g.types[dir][t]; ok && decl.name != "" { - return decl.name - } - return GoName(t.WIT(nil, t.TypeName()), true) -} - func (g *generator) typeDefRep(file *gen.File, dir wit.Direction, t *wit.TypeDef, goName string) string { return g.typeDefKindRep(file, dir, t.Kind, goName) } @@ -626,7 +618,7 @@ func (g *generator) typeDefKindRep(file *gen.File, dir wit.Direction, kind wit.T case *wit.Record: return g.recordRep(file, dir, kind, goName) case *wit.Tuple: - return g.tupleRep(file, dir, kind) + return g.tupleRep(file, dir, kind, goName) case *wit.Flags: return g.flagsRep(file, dir, kind, goName) case *wit.Enum: @@ -718,7 +710,7 @@ func (g *generator) primitiveRep(p wit.Primitive) string { } func (g *generator) recordRep(file *gen.File, dir wit.Direction, r *wit.Record, goName string) string { - exported := token.IsExported(goName) + exported := len(goName) == 0 || token.IsExported(goName) var b strings.Builder b.WriteString("struct {") for i, f := range r.Fields { @@ -744,13 +736,13 @@ func fieldName(name string, export bool) string { return GoName(name, export) } -func (g *generator) tupleRep(file *gen.File, dir wit.Direction, t *wit.Tuple) string { +func (g *generator) tupleRep(file *gen.File, dir wit.Direction, t *wit.Tuple, goName string) string { var b strings.Builder if typ := t.Type(); typ != nil { stringio.Write(&b, "[", strconv.Itoa(len(t.Types)), "]", g.typeRep(file, dir, typ)) } else if len(t.Types) == 0 || len(t.Types) > cm.MaxTuple { // Force struct representation - return g.typeDefKindRep(file, dir, t.Despecialize(), "") + return g.typeDefKindRep(file, dir, t.Despecialize(), goName) } else { stringio.Write(&b, file.Import(g.opts.cmPackage), ".Tuple") if len(t.Types) > 2 { @@ -1002,6 +994,14 @@ func (g *generator) typeDefShape(file *gen.File, dir wit.Direction, t *wit.TypeD return name } +// typeDefGoName returns a mangled Go name for t. +func (g *generator) typeDefGoName(dir wit.Direction, t *wit.TypeDef) string { + if decl, ok := g.types[dir][t]; ok && decl.name != "" { + return decl.name + } + return GoName(t.WIT(nil, t.TypeName()), true) +} + func (g *generator) lowerType(file *gen.File, dir wit.Direction, t wit.Type, input string) string { switch t := t.(type) { case nil: @@ -1089,12 +1089,14 @@ func (g *generator) lowerTuple(file *gen.File, dir wit.Direction, t *wit.TypeDef mono := tup.Type() afile := g.abiFile(file.Package) var b strings.Builder + var f int for i, tt := range tup.Types { for j := range tt.Flat() { if j > 0 { b.WriteString(", ") } - stringio.Write(&b, "f"+strconv.Itoa(i+j)) + stringio.Write(&b, "f"+strconv.Itoa(f)) + f++ } field := "v.F" + strconv.Itoa(i) if mono != nil { @@ -1856,13 +1858,17 @@ func (g *generator) defineExportedFunction(owner wit.Ident, f *wit.Function, dec if compoundParams.typ == nil { i := 0 for _, p := range callParams { - if p.typ == derefPointer(decl.wasm.params[i].typ) { + if i < len(decl.wasm.params) && p.typ == derefPointer(decl.wasm.params[i].typ) { stringio.Write(&b, p.name, " := *", decl.wasm.params[i].name, "\n") i++ continue } flat := p.typ.Flat() - stringio.Write(&b, p.name, " := ", g.liftType(file, dir, p.typ, g.liftTypeInput(file, dir, p.typ, decl.wasm.params[i:i+len(flat)])), "\n") + var input string + if len(flat) > 0 && len(decl.wasm.params) > 0 { + input = g.liftTypeInput(file, dir, p.typ, decl.wasm.params[i:i+len(flat)]) + } + stringio.Write(&b, p.name, " := ", g.liftType(file, dir, p.typ, input), "\n") i += len(flat) } } @@ -1921,21 +1927,27 @@ func (g *generator) defineExportedFunction(owner wit.Ident, f *wit.Function, dec if len(callResults) > 0 && compoundResults.typ == nil { i := 0 for _, r := range callResults { - flat := r.typ.Flat() - wr := decl.wasm.results[i] - if r.typ == derefPointer(wr.typ) { - stringio.Write(&b, wr.name, " = &", r.name, "\n") - i++ - continue + if i < len(decl.wasm.results) { + wr := decl.wasm.results[i] + if r.typ == derefPointer(wr.typ) { + stringio.Write(&b, wr.name, " = &", r.name, "\n") + i++ + continue + } } - for j := range flat { - if j > 0 { - b.WriteString(", ") + flat := r.typ.Flat() + if len(flat) == 0 { + stringio.Write(&b, "_ = ", r.name, "\n") + } else { + for j := range flat { + if j > 0 { + b.WriteString(", ") + } + b.WriteString(decl.wasm.results[i].name) + i++ } - b.WriteString(decl.wasm.results[i].name) - i++ + stringio.Write(&b, " = ", g.lowerType(file, dir, r.typ, r.name), "\n") } - stringio.Write(&b, " = ", g.lowerType(file, dir, r.typ, r.name), "\n") } }