* fixes #12015 by also checking kind of `typeNode` If a tuple field is aliased it'll appear the same as a ref type in a call to `getType` if only for the kind of the resulting `NimNode` is checked (that is a `nnkBracketExpr`) * fix test case due to #12017 and add more realistic test case Adds an additional test case, which includes generics and is closer to the real failure I encountered * remove previous fix and fix differently after all The previous fix was incomplete, because it failed for generics. Note that the `of "tuple"` is not actually needed, the `nnkBracketExpr` branch in the `else` branch would catch it too, but I decided to introduce it for clarity. However, the latter is actually needed, because it seems for aliases of `seq` we end up in it. * update comment about global `%` proc in json test
This commit is contained in:
parent
00d46ca1c0
commit
eff0837ff4
2 changed files with 49 additions and 4 deletions
|
|
@ -1369,11 +1369,20 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
||||||
for `forLoopI` in 0 ..< `jsonNode`.len: list[`forLoopI`] =`constructorNode`;
|
for `forLoopI` in 0 ..< `jsonNode`.len: list[`forLoopI`] =`constructorNode`;
|
||||||
list
|
list
|
||||||
)
|
)
|
||||||
|
of "tuple":
|
||||||
|
let typeNode = getTypeImpl(typeSym)
|
||||||
|
result = createConstructor(typeNode, jsonNode)
|
||||||
else:
|
else:
|
||||||
# Generic type.
|
# Generic type or some `seq[T]` alias
|
||||||
let obj = getType(typeSym)
|
let obj = getType(typeSym)
|
||||||
result = processType(typeSym, obj, jsonNode, false)
|
case obj.kind
|
||||||
|
of nnkBracketExpr:
|
||||||
|
# probably a `seq[T]` alias
|
||||||
|
let typeNode = getTypeImpl(typeSym)
|
||||||
|
result = createConstructor(typeNode, jsonNode)
|
||||||
|
else:
|
||||||
|
# generic type
|
||||||
|
result = processType(typeSym, obj, jsonNode, false)
|
||||||
of nnkSym:
|
of nnkSym:
|
||||||
# Handle JsonNode.
|
# Handle JsonNode.
|
||||||
if ($typeSym).cmpIgnoreStyle("jsonnode") == 0:
|
if ($typeSym).cmpIgnoreStyle("jsonnode") == 0:
|
||||||
|
|
@ -1385,7 +1394,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
||||||
if typeNode.typeKind == ntyDistinct:
|
if typeNode.typeKind == ntyDistinct:
|
||||||
result = createConstructor(typeNode, jsonNode)
|
result = createConstructor(typeNode, jsonNode)
|
||||||
elif obj.kind == nnkBracketExpr:
|
elif obj.kind == nnkBracketExpr:
|
||||||
# When `Sym "Foo"` turns out to be a `ref object`.
|
# When `Sym "Foo"` turns out to be a `ref object` or `tuple`
|
||||||
result = createConstructor(obj, jsonNode)
|
result = createConstructor(obj, jsonNode)
|
||||||
else:
|
else:
|
||||||
result = processType(typeSym, obj, jsonNode, false)
|
result = processType(typeSym, obj, jsonNode, false)
|
||||||
|
|
|
||||||
|
|
@ -517,6 +517,42 @@ when true:
|
||||||
doAssert v.name == "smith"
|
doAssert v.name == "smith"
|
||||||
doAssert MyRef(w).name == "smith"
|
doAssert MyRef(w).name == "smith"
|
||||||
|
|
||||||
|
# bug #12015
|
||||||
|
# The definition of the `%` proc needs to be here, since the `% c` calls below
|
||||||
|
# can only find our custom `%` proc for `Pix` if defined in global scope.
|
||||||
|
type
|
||||||
|
Pix = tuple[x, y: uint8, ch: uint16]
|
||||||
|
proc `%`(p: Pix): JsonNode =
|
||||||
|
result = %* { "x" : % p.x,
|
||||||
|
"y" : % p.y,
|
||||||
|
"ch" : % p.ch }
|
||||||
|
block:
|
||||||
|
type
|
||||||
|
Cluster = object
|
||||||
|
works: tuple[x, y: uint8, ch: uint16] # working
|
||||||
|
fails: Pix # previously broken
|
||||||
|
|
||||||
|
let data = (x: 123'u8, y: 53'u8, ch: 1231'u16)
|
||||||
|
let c = Cluster(works: data, fails: data)
|
||||||
|
let cFromJson = (% c).to(Cluster)
|
||||||
|
doAssert c == cFromJson
|
||||||
|
|
||||||
|
block:
|
||||||
|
# bug related to #12015
|
||||||
|
type
|
||||||
|
PixInt = tuple[x, y, ch: int]
|
||||||
|
SomePix = Pix | PixInt
|
||||||
|
Cluster[T: SomePix] = seq[T]
|
||||||
|
ClusterObject[T: SomePix] = object
|
||||||
|
data: Cluster[T]
|
||||||
|
RecoEvent[T: SomePix] = object
|
||||||
|
cluster: seq[ClusterObject[T]]
|
||||||
|
|
||||||
|
let data = @[(x: 123'u8, y: 53'u8, ch: 1231'u16)]
|
||||||
|
var c = RecoEvent[Pix](cluster: @[ClusterObject[Pix](data: data)])
|
||||||
|
let cFromJson = (% c).to(RecoEvent[Pix])
|
||||||
|
doAssert c == cFromJson
|
||||||
|
|
||||||
# TODO: when the issue with the limeted vm registers is solved, the
|
# TODO: when the issue with the limeted vm registers is solved, the
|
||||||
# exact same test as above should be evaluated at compile time as
|
# exact same test as above should be evaluated at compile time as
|
||||||
# well, to ensure that the vm functionality won't diverge from the
|
# well, to ensure that the vm functionality won't diverge from the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue