Misc macro things (#10612)

* Misc cleanup in macro code

Generate error messages using `error` instead of `assert`.

Fixes #10574

* Fix crash with hasCustomPragma on quoted fields

Use the `$` operator instead of reaching for the `strVal` field directly
This commit is contained in:
LemonBoy
2019-02-09 18:22:07 +01:00
committed by Andreas Rumpf
parent 467519f80d
commit 1e88bf1def
2 changed files with 19 additions and 14 deletions

View File

@@ -1027,7 +1027,10 @@ const
nnkCallStrLit, nnkHiddenCallConv}
proc expectKind*(n: NimNode; k: set[NimNodeKind]) {.compileTime.} =
assert n.kind in k, "Expected one of " & $k & ", got " & $n.kind
## checks that `n` is of kind `k`. If this is not the case,
## compilation aborts with an error message. This is useful for writing
## macros that check the AST that is passed to them.
if n.kind notin k: error("Expected one of " & $k & ", got " & $n.kind, n)
proc newProc*(name = newEmptyNode(); params: openArray[NimNode] = [newEmptyNode()];
body: NimNode = newStmtList(), procType = nnkProcDef): NimNode {.compileTime.} =
@@ -1035,7 +1038,8 @@ proc newProc*(name = newEmptyNode(); params: openArray[NimNode] = [newEmptyNode(
##
## The ``params`` array must start with the return type of the proc,
## followed by a list of IdentDefs which specify the params.
assert procType in RoutineNodes
if procType notin RoutineNodes:
error("Expected one of " & $RoutineNodes & ", got " & $procType)
result = newNimNode(procType).add(
name,
newEmptyNode(),
@@ -1077,7 +1081,8 @@ proc newEnum*(name: NimNode, fields: openArray[NimNode],
##
expectKind name, nnkIdent
doAssert len(fields) > 0, "Enum must contain at least one field"
if len(fields) < 1:
error("Enum must contain at least one field")
for field in fields:
expectKind field, {nnkIdent, nnkEnumFieldDef}
@@ -1133,7 +1138,7 @@ proc params*(someProc: NimNode): NimNode {.compileTime.} =
result = someProc[3]
proc `params=`* (someProc: NimNode; params: NimNode) {.compileTime.}=
someProc.expectRoutine
assert params.kind == nnkFormalParams
expectKind(params, nnkFormalParams)
someProc[3] = params
proc pragma*(someProc: NimNode): NimNode {.compileTime.} =
@@ -1144,7 +1149,7 @@ proc pragma*(someProc: NimNode): NimNode {.compileTime.} =
proc `pragma=`*(someProc: NimNode; val: NimNode){.compileTime.}=
## Set the pragma of a proc type
someProc.expectRoutine
assert val.kind in {nnkEmpty, nnkPragma}
expectKind(val, {nnkEmpty, nnkPragma})
someProc[4] = val
proc addPragma*(someProc, pragma: NimNode) {.compileTime.} =
@@ -1156,8 +1161,8 @@ proc addPragma*(someProc, pragma: NimNode) {.compileTime.} =
someProc.pragma = pragmaNode
pragmaNode.add(pragma)
template badNodeKind(k, f) =
assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`"
template badNodeKind(n, f) =
error("Invalid node kind " & $n.kind & " for macros.`" & $f & "`", n)
proc body*(someProc: NimNode): NimNode {.compileTime.} =
case someProc.kind:
@@ -1168,7 +1173,7 @@ proc body*(someProc: NimNode): NimNode {.compileTime.} =
of nnkForStmt:
return someProc.last
else:
badNodeKind someProc.kind, "body"
badNodeKind someProc, "body"
proc `body=`*(someProc: NimNode, val: NimNode) {.compileTime.} =
case someProc.kind
@@ -1179,7 +1184,7 @@ proc `body=`*(someProc: NimNode, val: NimNode) {.compileTime.} =
of nnkForStmt:
someProc[len(someProc)-1] = val
else:
badNodeKind someProc.kind, "body="
badNodeKind someProc, "body="
proc basename*(a: NimNode): NimNode {.compiletime, benign.}
@@ -1195,7 +1200,7 @@ proc `$`*(node: NimNode): string {.compileTime.} =
of nnkAccQuoted:
result = $node[0]
else:
badNodeKind node.kind, "$"
badNodeKind node, "$"
proc ident*(name: string): NimNode {.magic: "StrToIdent", noSideEffect.}
## Create a new ident node from a string
@@ -1281,7 +1286,7 @@ proc unpackPrefix*(node: NimNode): tuple[node: NimNode; op: string] {.
proc unpackInfix*(node: NimNode): tuple[left: NimNode; op: string;
right: NimNode] {.compileTime.} =
assert node.kind == nnkInfix
expectKind(node, nnkInfix)
result = (node[1], $node[0], node[2])
proc copy*(node: NimNode): NimNode {.compileTime.} =
@@ -1342,7 +1347,7 @@ else:
proc hasArgOfName*(params: NimNode; name: string): bool {.compiletime.}=
## Search nnkFormalParams for an argument.
assert params.kind == nnkFormalParams
expectKind(params, nnkFormalParams)
for i in 1 ..< params.len:
template node: untyped = params[i]
if name.eqIdent( $ node[0]):
@@ -1451,7 +1456,7 @@ proc customPragmaNode(n: NimNode): NimNode =
if varName.kind == nnkPostfix:
# This is a public field. We are skipping the postfix *
varName = varName[1]
if eqIdent(varName.strVal, name):
if eqIdent($varName, name):
return varNode[1]
if obj[1].kind == nnkOfInherit: # explore the parent object

View File

@@ -22,7 +22,7 @@ import custom_pragma
block: # A bit more advanced case
type
Subfield {.defaultValue: "catman".} = object
c* {.serializationKey: "cc".}: float
`c`* {.serializationKey: "cc".}: float
MySerializable = object
a {.serializationKey"asdf", defaultValue: 5.} : int