Skip to content

Commit f6b4fd5

Browse files
committed
update
Signed-off-by: George Lemon <georgelemon@protonmail.com>
1 parent 6a613b3 commit f6b4fd5

File tree

1 file changed

+49
-33
lines changed

1 file changed

+49
-33
lines changed

src/voodoo/setget.nim

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ proc genProcIdent(x: NimNode): NimNode {.compileTime.} =
3232
#
3333
# Setter
3434
#
35-
macro setter*(obj: untyped) =
35+
macro setters*(obj: untyped) =
3636
## Generate setter procs from object fields
3737
discard # todo
3838
39-
macro setter*(excludes: untyped, obj: untyped) =
39+
macro setters*(excludes: untyped, obj: untyped) =
4040
## Optionally, you can exclude fields from generation
4141
expectKind excludes, nnkBracket
4242
excludeFields = excludes.mapIt($it)
@@ -54,53 +54,69 @@ macro expandSetters* =
5454
#
5555
# Getter
5656
#
57+
proc walkField(f: NimNode, id: NimNode) {.compileTime.} =
58+
var
59+
procName: NimNode
60+
returnType = f[^2]
61+
fieldName: string
62+
for x in f[0..^3]:
63+
case x.kind
64+
of nnkIdent, nnkAccQuoted:
65+
if excludeFields.contains($x):
66+
continue
67+
fieldName = $x
68+
procName = genProcIdent(x)
69+
else: discard
70+
var body = newStmtList()
71+
add body, newCommentStmtNode("Getter handle to return `" & $fieldName & "`")
72+
add genGetters[id.strVal],
73+
newProc(
74+
nnkPostfix.newTree(ident("*"), procName),
75+
params = [
76+
returnType,
77+
nnkIdentDefs.newTree(
78+
ident(id.strVal[0].toLowerAscii & id.strVal[1..^1]),
79+
id,
80+
newEmptyNode()
81+
),
82+
],
83+
body = body
84+
)
85+
5786
macro getters*(obj: untyped) =
58-
## Generate getter procs from object fields
5987
let objident = obj[0][0][1]
60-
let objf = obj[2][0][2]
88+
var objf: NimNode
89+
if obj[2].kind == nnkRefTy:
90+
objf = obj[2][0][2]
91+
else:
92+
objf = obj[2][2]
6193
obj[0] = obj[0][0]
6294
expectKind objf, nnkRecList
6395
genGetters[objident.strVal] = newStmtList()
6496
for f in objf:
65-
var procName: NimNode
66-
var returnType = f[^2]
67-
var fieldName: string
68-
for x in f[0..^3]:
69-
case x.kind
70-
of nnkIdent, nnkAccQuoted:
71-
if excludeFields.contains($x):
72-
continue
73-
fieldName = $x
74-
procName = genProcIdent(x)
75-
else: discard
76-
var body = newStmtList()
77-
add body, newCommentStmtNode("Getter handle to return `" & $fieldName & "`")
78-
add genGetters[objident.strVal],
79-
newProc(
80-
nnkPostfix.newTree(ident("*"), procName),
81-
params = [
82-
returnType,
83-
nnkIdentDefs.newTree(
84-
ident(objident.strVal[0].toLowerAscii & objident.strVal[1..^1]),
85-
objident,
86-
newEmptyNode()
87-
),
88-
],
89-
body = body
90-
)
97+
case f.kind
98+
of nnkRecCase:
99+
for ff in f[1..^1]:
100+
expectKind(ff[1], nnkRecList)
101+
ff[1][0].walkField(objident)
102+
else:
103+
f.walkField(objident)
91104
obj
92105

93106
macro getters*(excludes: untyped, obj: untyped) =
94-
## Optionally, you can exclude fields from generation
95107
expectKind excludes, nnkBracket
96108
excludeFields = excludes.mapIt($it)
97109
echo obj[0].treeRepr
98110
add obj[0][1], ident("getters")
99111
obj
100112

101-
macro expandGetters* =
102-
## Required to inject the generated getters in your code
113+
macro expandGetters*(identRenameCallback: static proc(x: string): string = nil) =
114+
## This is required to insert generated getters
115+
## Use `identRename` to rename
103116
result = newStmtList()
104117
for k, x in genGetters:
118+
if identRenameCallback != nil:
119+
for p in x:
120+
p[0][1] = ident(identRenameCallback(p[0][1].strVal))
105121
add result, x
106122
clear(genGetters)

0 commit comments

Comments
 (0)