mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-04 04:02:41 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user