diff --git a/tests/lxdrgen.lxdr b/tests/lxdrgen.lxdr index 6c53de5..41973f8 100644 --- a/tests/lxdrgen.lxdr +++ b/tests/lxdrgen.lxdr @@ -20,4 +20,9 @@ struct Struct { case NOTHING: void; } u<>; + + union Onion switch (Enum tag) { + case NOTHING: + void; + } o; }; diff --git a/tools/lxdrgen-c.awk b/tools/lxdrgen-c.awk index 0d43785..e898aae 100644 --- a/tools/lxdrgen-c.awk +++ b/tools/lxdrgen-c.awk @@ -259,7 +259,7 @@ function codegen_union_struct( \ "\t\tbreak;\n") } -function codegen_union(name, cg, f, ctype, funcname) { +function codegen_union(name, cg, exhaustive, f, ctype, funcname) { ctype = "union " PrefixLower cameltosnake(name) print "" print ctype " {" diff --git a/tools/lxdrgen-go.awk b/tools/lxdrgen-go.awk index f9163bb..f129bc1 100644 --- a/tools/lxdrgen-go.awk +++ b/tools/lxdrgen-go.awk @@ -467,7 +467,7 @@ function codegen_union_struct(name, casename, cg, scg, structname, init) { "\t\tu.Interface = &s\n") } -function codegen_union(name, cg, gotype, tagvar) { +function codegen_union(name, cg, exhaustive, gotype, tagvar) { gotype = PrefixCamel name print "type " gotype " struct {" print "\tInterface any" diff --git a/tools/lxdrgen-mjs.awk b/tools/lxdrgen-mjs.awk index 01ee97d..4eaac63 100644 --- a/tools/lxdrgen-mjs.awk +++ b/tools/lxdrgen-mjs.awk @@ -208,7 +208,7 @@ function codegen_union_struct(name, casename, cg, scg, structname) { "\t}\n") } -function codegen_union(name, cg, tagvar) { +function codegen_union(name, cg, exhaustive, tagvar) { tagvar = cg["tagname"] print "" diff --git a/tools/lxdrgen-swift.awk b/tools/lxdrgen-swift.awk index 28554c9..33b1f73 100644 --- a/tools/lxdrgen-swift.awk +++ b/tools/lxdrgen-swift.awk @@ -246,7 +246,7 @@ function codegen_union_struct(name, casename, cg, scg, swifttype) { delete scg[i] } -function codegen_union(name, cg, swifttype, init) { +function codegen_union(name, cg, exhaustive, swifttype, init) { # Classes don't have automatic member-wise initializers, # thus using structs and protocols. swifttype = PrefixCamel name @@ -255,6 +255,10 @@ function codegen_union(name, cg, swifttype, init) { print "\tvar " cg["tagname"] ": " CodegenSwiftType[cg["tagtype"]] " { get }" print "}" + if (!exhaustive) + append(cg, "cases", "\tdefault:\n" \ + "\t\tthrow RelayReader.ReadError.unexpectedValue\n") + init = decapitalize(swifttype) print "" print "public func " init \ @@ -262,11 +266,7 @@ function codegen_union(name, cg, swifttype, init) { print "\tlet " cg["tagname"] ": " CodegenSwiftType[cg["tagtype"]] \ " = try from.read()" print "\tswitch " cg["tagname"] " {" - # TODO: Only generate the default if there are remaining values, - # so that swiftc doesn't produce warnings. - print cg["cases"] "\tdefault:" - print "\t\tthrow RelayReader.ReadError.unexpectedValue" - print"\t}" + print cg["cases"] "\t}" print "}" CodegenSwiftType[name] = swifttype diff --git a/tools/lxdrgen.awk b/tools/lxdrgen.awk index f77f19f..e5259b7 100644 --- a/tools/lxdrgen.awk +++ b/tools/lxdrgen.awk @@ -217,7 +217,8 @@ function defstruct( name, d, cg) { return name } -function defunion( name, tag, tagtype, tagvalue, cg, scg, d, a, i, unseen) { +function defunion( name, tag, tagtype, tagvalue, cg, scg, d, a, i, + unseen, exhaustive) { delete cg[0] delete scg[0] delete d[0] @@ -258,9 +259,14 @@ function defunion( name, tag, tagtype, tagvalue, cg, scg, d, a, i, unseen) { if (tagvalue) codegen_union_struct(name, tagvalue, cg, scg) - # What remains non-zero in unseen[2..] is simply not recognized/allowed. + # Unseen cases are simply not recognized/allowed. + exhaustive = 1 + for (i in unseen) + if (i && unseen[i]) + exhaustive = 0 + Types[name] = "union" - codegen_union(name, cg) + codegen_union(name, cg, exhaustive) return name }