As reported in #189, the `edges` field of JSON graph output refers to
information not reflected in the rest of the output, specifically the
vertex IDs. This patch adds that information to the `ToJSON` instance
for `ControlFlowVertex`. It also includes a `toEncoding` instance for
a free speed boost.
During this patch, I realized that, because `hash` tends to return a
large number (since `Int` is 64-bit), we may run into errors when
decoding JSON. One example hash is `3500157981503982114`; passing that
to a JS engine's `Number.isSafeInteger` function returns false. The
correct thing to do here is return ids as strings, which I have done.
This is backwards-incompatible, but since this information was never
properly exposed, the impact is negligable.
We define the DiffTreeVertex protobuf message like so:
```protobuf
message DiffTreeVertex {
int32 diff_vertex_id = 1;
oneof diff_term {
DeletedTerm deleted = 2;
InsertedTerm inserted = 3;
ReplacedTerm replaced = 4;
MergedTerm merged = 5;
}
}
```
This is turned into two Haskell types, a toplevel `DiffTreeVertex` type
and a `DiffTreeVertexDiffTerm` type that represents the anonymous
`oneof` type. Said types looked like so:
```haskell
data DiffTreeVertexDiffTerm
= Deleted (Maybe DeletedTerm)
| Inserted (Maybe InsertedTerm)
| Replaced (Maybe ReplacedTerm)
| Merged (Maybe MergedTerm)
deriving stock (Eq, Ord, Show, Generic)
deriving anyclass (Proto3.Message, Proto3.Named, NFData)
```
This is the wrong representation, as it neglects to account for the
fact that options could be added to the `diff_term` stanza. A sum type
does not provide enough constructors to handle the case of when none
of `deleted`, `inserted`, `replaced` etc. is `Just` anything. A more
correct definition follows:
```haskell
data DiffTreeVertexDiffTerm = DiffTreeVertexDiffTerm
{ deleted :: Maybe DeletedTerm
, inserted :: Maybe InsertedTerm
, replaced :: Maybe ReplacedTerm
, merged :: Maybe MergedTerm
}
```
This patch applies the above change, using `-XPatternSynonyms` to
provide backwards-compatible API shims. Though this changes JSON
output format (through the `ToJSON` instance), it should have no
bearing on backwards compatibility in protobuf objects, since there is
no way to consume diff trees as protobufs as of this writing.
Fixes#168.