Clonkk fix2 11923 (#19451)

* fix nnkBracketExpr not compiling for getImpl on customPragmaNode

* fix test import

* fix alias not working with hasCustomPragmas
This commit is contained in:
Regis Caillaud 2022-02-02 09:44:51 +01:00 • committed by GitHub
commit 486cb09ec2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 5 deletions

View file

@ -1493,6 +1493,22 @@ macro expandMacros*(body: typed): untyped =
echo body.toStrLit echo body.toStrLit
result = body result = body
proc extractTypeImpl(n: NimNode): NimNode =
## attempts to extract the type definition of the given symbol
case n.kind
of nnkSym: # can extract an impl
result = n.getImpl.extractTypeImpl()
of nnkObjectTy, nnkRefTy, nnkPtrTy: result = n
of nnkBracketExpr:
if n.typeKind == ntyTypeDesc:
result = n[1].extractTypeImpl()
else:
doAssert n.typeKind == ntyGenericInst
result = n[0].getImpl()
of nnkTypeDef:
result = n[2]
else: error("Invalid node to retrieve type implementation of: " & $n.kind)
proc customPragmaNode(n: NimNode): NimNode = proc customPragmaNode(n: NimNode): NimNode =
expectKind(n, {nnkSym, nnkDotExpr, nnkBracketExpr, nnkTypeOfExpr, nnkCheckedFieldExpr}) expectKind(n, {nnkSym, nnkDotExpr, nnkBracketExpr, nnkTypeOfExpr, nnkCheckedFieldExpr})
let let
@ -1501,7 +1517,10 @@ proc customPragmaNode(n: NimNode): NimNode =
if typ.kind == nnkBracketExpr and typ.len > 1 and typ[1].kind == nnkProcTy: if typ.kind == nnkBracketExpr and typ.len > 1 and typ[1].kind == nnkProcTy:
return typ[1][1] return typ[1][1]
elif typ.typeKind == ntyTypeDesc: elif typ.typeKind == ntyTypeDesc:
let impl = typ[1].getImpl() let impl = getImpl(
if kind(typ[1]) == nnkBracketExpr: typ[1][0]
else: typ[1]
)
if impl[0].kind == nnkPragmaExpr: if impl[0].kind == nnkPragmaExpr:
return impl[0][1] return impl[0][1]
else: else:
@ -1524,14 +1543,12 @@ proc customPragmaNode(n: NimNode): NimNode =
let name = $(if n.kind == nnkCheckedFieldExpr: n[0][1] else: n[1]) let name = $(if n.kind == nnkCheckedFieldExpr: n[0][1] else: n[1])
let typInst = getTypeInst(if n.kind == nnkCheckedFieldExpr or n[0].kind == nnkHiddenDeref: n[0][0] else: n[0]) let typInst = getTypeInst(if n.kind == nnkCheckedFieldExpr or n[0].kind == nnkHiddenDeref: n[0][0] else: n[0])
var typDef = getImpl( var typDef = getImpl(
if typInst.kind == nnkVarTy or if typInst.kind in {nnkVarTy, nnkBracketExpr}: typInst[0]
typInst.kind == nnkBracketExpr:
typInst[0]
else: typInst else: typInst
) )
while typDef != nil: while typDef != nil:
typDef.expectKind(nnkTypeDef) typDef.expectKind(nnkTypeDef)
let typ = typDef[2] let typ = typDef[2].extractTypeImpl()
typ.expectKind({nnkRefTy, nnkPtrTy, nnkObjectTy}) typ.expectKind({nnkRefTy, nnkPtrTy, nnkObjectTy})
let isRef = typ.kind in {nnkRefTy, nnkPtrTy} let isRef = typ.kind in {nnkRefTy, nnkPtrTy}
if isRef and typ[0].kind in {nnkSym, nnkBracketExpr}: # defines ref type for another object(e.g. X = ref X) if isRef and typ[0].kind in {nnkSym, nnkBracketExpr}: # defines ref type for another object(e.g. X = ref X)

View file

@ -20,16 +20,22 @@ block:
MyGenericObj[T] = object MyGenericObj[T] = object
myField1, myField2 {.myAttr: "hi".}: int myField1, myField2 {.myAttr: "hi".}: int
MyOtherObj = MyObj
var o: MyObj var o: MyObj
static: static:
doAssert o.myField2.hasCustomPragma(myAttr) doAssert o.myField2.hasCustomPragma(myAttr)
doAssert(not o.myField1.hasCustomPragma(myAttr)) doAssert(not o.myField1.hasCustomPragma(myAttr))
doAssert(not o.myField1.hasCustomPragma(MyObj))
doAssert(not o.myField1.hasCustomPragma(MyOtherObj))
var ogen: MyGenericObj[int] var ogen: MyGenericObj[int]
static: static:
doAssert ogen.myField2.hasCustomPragma(myAttr) doAssert ogen.myField2.hasCustomPragma(myAttr)
doAssert(not ogen.myField1.hasCustomPragma(myAttr)) doAssert(not ogen.myField1.hasCustomPragma(myAttr))
doAssert(not ogen.myField1.hasCustomPragma(MyGenericObj))
doAssert(not ogen.myField1.hasCustomPragma(MyGenericObj))
import custom_pragma import custom_pragma