Skip to content

Commit

Permalink
Fix #62 (#75)
Browse files Browse the repository at this point in the history
* Fix #62

- Supports more than one pragma parameter (return tuple)
- Returns nil if there are zero parameters in the pragma (like std)
  • Loading branch information
gabbhack authored Feb 10, 2021
1 parent a0e8ec4 commit 04f8150
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
14 changes: 12 additions & 2 deletions stew/shims/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -426,4 +437,3 @@ template genStmtList*(body: untyped) =
template genSimpleExpr*(body: untyped): untyped =
macro payload: untyped = body
payload()

42 changes: 42 additions & 0 deletions tests/test_macros.nim
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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

0 comments on commit 04f8150

Please sign in to comment.