Commit 45c23897 authored by Kenton Varda's avatar Kenton Varda

Fix bug with dynamic unions.

parent 6e335427
...@@ -733,6 +733,14 @@ TEST(DynamicApi, ConversionFailures) { ...@@ -733,6 +733,14 @@ TEST(DynamicApi, ConversionFailures) {
EXPECT_ANY_THROW(root.set("boolField", 1)); EXPECT_ANY_THROW(root.set("boolField", 1));
} }
TEST(DynamicApi, LateUnion) {
MallocMessageBuilder builder;
auto root = builder.initRoot<DynamicStruct>(Schema::from<test::TestLateUnion>());
root.get("theUnion").as<DynamicUnion>().set("qux", "hello");
EXPECT_EQ("hello", root.as<test::TestLateUnion>().getTheUnion().getQux());
}
} // namespace } // namespace
} // namespace internal } // namespace internal
} // namespace capnproto } // namespace capnproto
...@@ -150,7 +150,7 @@ Maybe<StructSchema::Member> StructSchema::Union::findMemberByName(Text::Reader n ...@@ -150,7 +150,7 @@ Maybe<StructSchema::Member> StructSchema::Union::findMemberByName(Text::Reader n
StructSchema::Member StructSchema::Union::getMemberByName(Text::Reader name) const { StructSchema::Member StructSchema::Union::getMemberByName(Text::Reader name) const {
Maybe<StructSchema::Member> member = findMemberByName(name); Maybe<StructSchema::Member> member = findMemberByName(name);
PRECOND(member != nullptr, "struct has no such member", name); PRECOND(member != nullptr, "union has no such member", name);
return *member; return *member;
} }
......
...@@ -339,3 +339,18 @@ struct TestListDefaults { ...@@ -339,3 +339,18 @@ struct TestListDefaults {
textListList = [["foo", "bar"], ["baz"], ["qux", "corge"]], textListList = [["foo", "bar"], ["baz"], ["qux", "corge"]],
structListList = [[(int32Field = 123), (int32Field = 456)], [(int32Field = 789)]]); structListList = [[(int32Field = 123), (int32Field = 456)], [(int32Field = 789)]]);
} }
struct TestLateUnion {
# Test what happens if the unions are the first ordinals in the struct. At one point this was
# broken for the dynamic API.
foo @0 :Int32;
bar @1 :Text;
baz @2 :Int16;
theUnion @3 union {
qux @4 :Text;
corge @5 :List(Int32);
grault @6 :Float32;
}
}
...@@ -287,8 +287,8 @@ memberTable (DescStruct desc) = let ...@@ -287,8 +287,8 @@ memberTable (DescStruct desc) = let
$ List.sortBy (compare `on` ordinal) $ structMembers desc $ List.sortBy (compare `on` ordinal) $ structMembers desc
-- Fields of each union. -- Fields of each union.
innerMembers = zipWith indexedUnionMembers [1..] innerMembers = catMaybes $ zipWith indexedUnionMembers [1..]
$ List.sortBy (compare `on` unionNumber) $ structUnions desc $ List.sortBy (compare `on` ordinal) $ structMembers desc
ordinal (DescField f) = fieldNumber f ordinal (DescField f) = fieldNumber f
ordinal (DescUnion u) = unionNumber u ordinal (DescUnion u) = unionNumber u
...@@ -298,8 +298,10 @@ memberTable (DescStruct desc) = let ...@@ -298,8 +298,10 @@ memberTable (DescStruct desc) = let
memberName (DescUnion u) = Just $ unionName u memberName (DescUnion u) = Just $ unionName u
memberName _ = Nothing memberName _ = Nothing
indexedUnionMembers i u = zip (memberIndexes i) $ mapMaybe memberName indexedUnionMembers i (DescUnion u) =
$ List.sortBy (compare `on` ordinal) $ unionMembers u Just $ zip (memberIndexes i) $ mapMaybe memberName $
List.sortBy (compare `on` ordinal) $ unionMembers u
indexedUnionMembers _ _ = Nothing
in concat $ topMembers : innerMembers in concat $ topMembers : innerMembers
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment