From 04f8150a080e2db4ddd7959ba89549f45494af80 Mon Sep 17 00:00:00 2001 From: Gabben <43146729+gabbhack@users.noreply.github.com> Date: Wed, 10 Feb 2021 18:10:08 +0500 Subject: [PATCH] Fix #62 (#75) * Fix #62 - Supports more than one pragma parameter (return tuple) - Returns nil if there are zero parameters in the pragma (like std) --- stew/shims/macros.nim | 14 ++++++++++++-- tests/test_macros.nim | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/stew/shims/macros.nim b/stew/shims/macros.nim index f9b6e7e..3fa9fc4 100644 --- a/stew/shims/macros.nim +++ b/stew/shims/macros.nim @@ -212,8 +212,19 @@ proc getPragma(T: NimNode, lookedUpField: string, pragma: NimNode): NimNode = error "The type " & $Tresolved & " doesn't have a field named " & lookedUpField macro getCustomPragmaFixed*(T: type, field: static string, pragma: typed{nkSym}): untyped = + result = nil let p = getPragma(T, field, pragma) - if p != nil and p.len == 2: p[1] else: p + + if p != nil and p.len > 0: + if p.len == 2: + result = p[1] + else: + let def = p[0].getImpl[3] + result = newTree(nnkPar) + for i in 1 ..< def.len: + let key = def[i][0] + let val = p[i] + result.add newTree(nnkExprColonExpr, key, val) macro hasCustomPragmaFixed*(T: type, field: static string, pragma: typed{nkSym}): untyped = newLit(getPragma(T, field, pragma) != nil) @@ -426,4 +437,3 @@ template genStmtList*(body: untyped) = template genSimpleExpr*(body: untyped): untyped = macro payload: untyped = body payload() - diff --git a/tests/test_macros.nim b/tests/test_macros.nim index b223c2e..1565194 100644 --- a/tests/test_macros.nim +++ b/tests/test_macros.nim @@ -1,7 +1,23 @@ import + unittest, ../stew/shims/macros + +template unknown() {.pragma.} +template zero() {.pragma.} +template one(one: string) {.pragma.} +template two(one: string, two: string) {.pragma.} + type + MyType[T] = object + myField {.zero, one("foo"), two("foo", "bar")}: string + myGeneric {.zero.}: T + case kind {.zero.}: bool + of true: + first {.zero.}: string + else: + second {.zero.}: string + FieldKind = enum KindA KindB @@ -40,3 +56,29 @@ static: "anotherDerivedField" ] +let myType = MyType[string](myField: "test", myGeneric: "test", kind: true, first: "test") + +suite "Macros": + test "hasCustomPragmaFixed": + check: + not myType.type.hasCustomPragmaFixed("myField", unknown) + myType.type.hasCustomPragmaFixed("myField", zero) + myType.type.hasCustomPragmaFixed("myField", one) + myType.type.hasCustomPragmaFixed("myField", two) + + myType.type.hasCustomPragmaFixed("myGeneric", zero) + myType.type.hasCustomPragmaFixed("kind", zero) + myType.type.hasCustomPragmaFixed("first", zero) + myType.type.hasCustomPragmaFixed("second", zero) + + test "getCustomPragmaFixed": + check: + myType.type.getCustomPragmaFixed("myField", unknown).isNil + myType.type.getCustomPragmaFixed("myField", zero).isNil + myType.type.getCustomPragmaFixed("myField", one) is string + myType.type.getCustomPragmaFixed("myField", two) is tuple[one: string, two: string] + + myType.type.getCustomPragmaFixed("myGeneric", zero).isNil + myType.type.getCustomPragmaFixed("kind", zero).isNil + myType.type.getCustomPragmaFixed("first", zero).isNil + myType.type.getCustomPragmaFixed("second", zero).isNil