* fixed macros.getTypeImpl for a symbol of type tyGenericBody * added test case and commented test code
This commit is contained in:
parent
b826f85731
commit
ec50dab57d
3 changed files with 57 additions and 21 deletions
|
|
@ -175,7 +175,12 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
|
||||||
result.add mapTypeToAst(t.sons[i], info)
|
result.add mapTypeToAst(t.sons[i], info)
|
||||||
else:
|
else:
|
||||||
result = mapTypeToAstX(t.lastSon, info, inst, allowRecursion)
|
result = mapTypeToAstX(t.lastSon, info, inst, allowRecursion)
|
||||||
of tyGenericBody, tyOrdinal:
|
of tyGenericBody:
|
||||||
|
if inst:
|
||||||
|
result = mapTypeToAstX(t.lastSon, info, inst, true)
|
||||||
|
else:
|
||||||
|
result = mapTypeToAst(t.lastSon, info)
|
||||||
|
of tyOrdinal:
|
||||||
result = mapTypeToAst(t.lastSon, info)
|
result = mapTypeToAst(t.lastSon, info)
|
||||||
of tyDistinct:
|
of tyDistinct:
|
||||||
if inst:
|
if inst:
|
||||||
|
|
|
||||||
|
|
@ -21,49 +21,67 @@ proc symToIdent(x: NimNode): NimNode =
|
||||||
for c in x:
|
for c in x:
|
||||||
result.add symToIdent(c)
|
result.add symToIdent(c)
|
||||||
|
|
||||||
|
# check getTypeInst and getTypeImpl for given symbol x
|
||||||
macro testX(x,inst0: typed; recurse: static[bool]; implX: stmt): typed =
|
macro testX(x,inst0: typed; recurse: static[bool]; implX: stmt): typed =
|
||||||
|
# check that getTypeInst(x) equals inst0
|
||||||
let inst = x.getTypeInst
|
let inst = x.getTypeInst
|
||||||
let impl = x.getTypeImpl
|
|
||||||
let inst0r = inst0.symToIdent.treeRepr
|
|
||||||
let instr = inst.symToIdent.treeRepr
|
let instr = inst.symToIdent.treeRepr
|
||||||
#echo inst0r
|
let inst0r = inst0.symToIdent.treeRepr
|
||||||
#echo instr
|
#echo instr
|
||||||
|
#echo inst0r
|
||||||
doAssert(instr == inst0r)
|
doAssert(instr == inst0r)
|
||||||
|
|
||||||
|
# check that getTypeImpl(x) is correct
|
||||||
|
# if implX is nil then compare to inst0
|
||||||
|
# else we expect implX to be a type definition
|
||||||
|
# and we extract the implementation from that
|
||||||
|
let impl = x.getTypeImpl
|
||||||
var impl0 =
|
var impl0 =
|
||||||
if implX.kind == nnkNilLit: inst0
|
if implX.kind == nnkNilLit: inst0
|
||||||
else: implX[0][2]
|
else: implX[0][2]
|
||||||
let impl0r = impl0.symToIdent.treerepr
|
|
||||||
let implr = impl.symToIdent.treerepr
|
let implr = impl.symToIdent.treerepr
|
||||||
#echo impl0r
|
let impl0r = impl0.symToIdent.treerepr
|
||||||
#echo implr
|
#echo implr
|
||||||
|
#echo impl0r
|
||||||
doAssert(implr == impl0r)
|
doAssert(implr == impl0r)
|
||||||
template echoString(s:string) = echo s.replace("\n","\n ")
|
|
||||||
result = newStmtList()
|
result = newStmtList()
|
||||||
|
#template echoString(s: string) = echo s.replace("\n","\n ")
|
||||||
#result.add getAst(echoString(" " & inst0.repr))
|
#result.add getAst(echoString(" " & inst0.repr))
|
||||||
#result.add getAst(echoString(" " & inst.repr))
|
#result.add getAst(echoString(" " & inst.repr))
|
||||||
#result.add getAst(echoString(" " & impl0.repr))
|
#result.add getAst(echoString(" " & impl0.repr))
|
||||||
#result.add getAst(echoString(" " & impl.repr))
|
#result.add getAst(echoString(" " & impl.repr))
|
||||||
|
|
||||||
if recurse:
|
if recurse:
|
||||||
template testDecl(n, m :typed) =
|
# now test using a newly formed variable of type getTypeInst(x)
|
||||||
|
template testDecl(n,m: typed) =
|
||||||
testV(n, false):
|
testV(n, false):
|
||||||
type _ = m
|
type _ = m
|
||||||
result.add getAst(testDecl(inst.symToIdent, impl.symToIdent))
|
result.add getAst(testDecl(inst.symToIdent, impl.symToIdent))
|
||||||
|
|
||||||
|
# test with a variable (instance) of type
|
||||||
template testV(inst, recurse, impl) =
|
template testV(inst, recurse, impl) =
|
||||||
block:
|
block:
|
||||||
#echo "testV(" & astToStr(inst) & ", " & $recurse & "):" & astToStr(impl)
|
#echo "testV(" & astToStr(inst) & ", " & $recurse & "):" & astToStr(impl)
|
||||||
var x: inst
|
var x: inst
|
||||||
testX(x, inst, recurse, impl)
|
testX(x, inst, recurse, impl)
|
||||||
template testT(inst, recurse) =
|
|
||||||
block:
|
|
||||||
type myType = inst
|
|
||||||
testV(myType, recurse):
|
|
||||||
type _ = inst
|
|
||||||
|
|
||||||
|
# test with a newly created typedesc (myType)
|
||||||
|
# using the passed type as the implementation
|
||||||
|
template testT(impl, recurse) =
|
||||||
|
block:
|
||||||
|
type myType = impl
|
||||||
|
testV(myType, recurse):
|
||||||
|
type _ = impl
|
||||||
|
|
||||||
|
# test a built-in type whose instance is equal to the implementation
|
||||||
template test(inst) =
|
template test(inst) =
|
||||||
testT(inst, false)
|
testT(inst, false)
|
||||||
testV(inst, true, nil)
|
testV(inst, true, nil)
|
||||||
template test(inst, impl) = testV(inst, true, impl)
|
|
||||||
|
# test a custom type with provided implementation
|
||||||
|
template test(inst, impl) =
|
||||||
|
testV(inst, true, impl)
|
||||||
|
|
||||||
type
|
type
|
||||||
Model = object of RootObj
|
Model = object of RootObj
|
||||||
|
|
@ -87,9 +105,12 @@ type
|
||||||
value:T
|
value:T
|
||||||
Foo[N:static[int],T] = object
|
Foo[N:static[int],T] = object
|
||||||
Bar[N:static[int],T] = object
|
Bar[N:static[int],T] = object
|
||||||
#baz:Foo[N+1,GenericObject[T]]
|
#baz:Foo[N+1,GenericObject[T]] # currently fails
|
||||||
baz:Foo[N,GenericObject[T]]
|
baz:Foo[N,GenericObject[T]]
|
||||||
|
|
||||||
|
Generic[T] = seq[int]
|
||||||
|
Concrete = Generic[int]
|
||||||
|
|
||||||
test(bool)
|
test(bool)
|
||||||
test(char)
|
test(char)
|
||||||
test(int)
|
test(int)
|
||||||
|
|
@ -97,13 +118,17 @@ test(float)
|
||||||
test(ptr int)
|
test(ptr int)
|
||||||
test(ref int)
|
test(ref int)
|
||||||
test(array[1..10,Bar[2,Foo[3,float]]])
|
test(array[1..10,Bar[2,Foo[3,float]]])
|
||||||
|
test(array[MyEnum,Bar[2,Foo[3,float]]])
|
||||||
test(distinct Bar[2,Foo[3,float]])
|
test(distinct Bar[2,Foo[3,float]])
|
||||||
test(tuple[a:int,b:Foo[-1,float]])
|
test(tuple[a:int,b:Foo[-1,float]])
|
||||||
#test(MyEnum):
|
|
||||||
# type _ = enum
|
|
||||||
# valueA, valueB, valueC
|
|
||||||
test(set[MyEnum])
|
|
||||||
test(seq[int])
|
test(seq[int])
|
||||||
|
test(set[MyEnum])
|
||||||
|
test(proc (a: int, b: Foo[2,float]))
|
||||||
|
test(proc (a: int, b: Foo[2,float]): Bar[3,int])
|
||||||
|
|
||||||
|
test(MyEnum):
|
||||||
|
type _ = enum
|
||||||
|
valueA, valueB, valueC
|
||||||
test(Bar[2,Foo[3,float]]):
|
test(Bar[2,Foo[3,float]]):
|
||||||
type _ = object
|
type _ = object
|
||||||
baz: Foo[2, GenericObject[Foo[3, float]]]
|
baz: Foo[2, GenericObject[Foo[3, float]]]
|
||||||
|
|
@ -118,8 +143,12 @@ test(Tree):
|
||||||
value: int
|
value: int
|
||||||
left: ref Tree
|
left: ref Tree
|
||||||
right: ref Tree
|
right: ref Tree
|
||||||
test(proc (a: int, b: Foo[2,float]))
|
test(Concrete):
|
||||||
test(proc (a: int, b: Foo[2,float]): Bar[3,int])
|
type _ = Generic[int]
|
||||||
|
test(Generic[int]):
|
||||||
|
type _ = seq[int]
|
||||||
|
test(Generic[float]):
|
||||||
|
type _ = seq[int]
|
||||||
|
|
||||||
# bug #4862
|
# bug #4862
|
||||||
static:
|
static:
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ Changes affecting backwards compatibility
|
||||||
AST that is the same as what is used to define an enum. Previously the AST
|
AST that is the same as what is used to define an enum. Previously the AST
|
||||||
returned had a repeated ``EnumTy`` node and was missing the initial pragma
|
returned had a repeated ``EnumTy`` node and was missing the initial pragma
|
||||||
node (which is currently empty for an enum).
|
node (which is currently empty for an enum).
|
||||||
|
- ``macros.getTypeImpl`` now correctly returns the implementation for a symbol
|
||||||
|
of type ``tyGenericBody``.
|
||||||
- If the dispatcher parameter's value used in multi method is ``nil``,
|
- If the dispatcher parameter's value used in multi method is ``nil``,
|
||||||
a ``NilError`` exception is raised. The old behavior was that the method
|
a ``NilError`` exception is raised. The old behavior was that the method
|
||||||
would be a ``nop`` then.
|
would be a ``nop`` then.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue