Skip to content

Commit

Permalink
Fix #16
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabben committed Feb 10, 2023
1 parent 5a4e037 commit 08144b5
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 174 deletions.
202 changes: 30 additions & 172 deletions src/deser/macroutils/parsing/field.nim
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,7 @@ func fromPragma*(featuresTy: typedesc[FieldFeatures], pragma: Option[NimNode]):

func fromBranch*(branchTy: typedesc[FieldBranch], branch: NimNode): seq[FieldBranch]

func getType(identDefs: NimNode): NimNode

func getNameIdent(identDefs: NimNode): NimNode

func getPragma(identDefs: NimNode): Option[NimNode]

func isPublic(identDefs: NimNode): bool
func unpackIdentDefs(identDefs: NimNode): tuple[typeNode, name: NimNode, pragma: Option[NimNode], isPublic: bool]

func deSymBracketExpr(bracket: NimNode): NimNode

Expand Down Expand Up @@ -136,11 +130,13 @@ func fromIdentDefs*(fieldTy: typedesc[Field], identDefs: NimNode): Field =
## Parse a field from an identDefs node
assertKind identDefs, {nnkIdentDefs}

let (typeNode, nameIdent, pragmas, isPublic) = unpackIdentDefs(identDefs)

initField(
nameIdent=getNameIdent(identDefs),
typeNode=getType(identDefs),
features=FieldFeatures.fromPragma(getPragma(identDefs)),
public=isPublic(identDefs),
nameIdent=nameIdent,
typeNode=typeNode,
features=FieldFeatures.fromPragma(pragmas),
public=isPublic,
isCase=false,
branches=newSeqOfCap[FieldBranch](0)
)
Expand All @@ -157,12 +153,14 @@ func fromRecCase*(fieldTy: typedesc[Field], recCase: NimNode): Field =
{.warning[UnsafeSetLen]: off.}
branches.add FieldBranch.fromBranch(branch)
{.warning[UnsafeSetLen]: on.}

let (typeNode, nameIdent, pragmas, isPublic) = unpackIdentDefs(identDefs)

initField(
nameIdent=getNameIdent(identDefs),
typeNode=getType(identDefs),
features=FieldFeatures.fromPragma(getPragma(identDefs)),
public=isPublic(identDefs),
nameIdent=nameIdent,
typeNode=typeNode,
features=FieldFeatures.fromPragma(pragmas),
public=isPublic,
isCase=true,
branches=branches
)
Expand Down Expand Up @@ -273,70 +271,30 @@ func fromPragma*(featuresTy: typedesc[FieldFeatures], pragma: Option[NimNode]):
else:
result = initEmptyFieldFeatures()

func getType(identDefs: NimNode): NimNode =
## Get the type of the field from an identDefs node

assertMatch identDefs:
IdentDefs[_, @typeNode, _]

case typeNode.kind
# generic
of nnkBracketExpr:
deSymBracketExpr(typeNode)
else:
typeNode

func getNameIdent(identDefs: NimNode): NimNode =
## Get the name of the field from an identDefs node

func unpackIdentDefs(identDefs: NimNode): tuple[typeNode, name: NimNode, pragma: Option[NimNode], isPublic: bool] =
assertMatch identDefs:
IdentDefs[
PostFix[_, @name is Ident()] |
(@name is Ident()) |
PragmaExpr[
Postfix[_, @name is Ident()] |
(@name is Ident()),
_
],
_,
_
]

name

func getPragma(identDefs: NimNode): Option[NimNode] =
## Get the pragma from an identDefs

assertMatch identDefs:
IdentDefs[
(
PragmaExpr[_, @pragma is Pragma()] |
Ident() |
PostFix[_, Ident()]
),
_,
PragmaExpr[@name is Ident(), @pragma is Pragma()] |
(@public is Postfix[_, @name is Ident()]) |
PragmaExpr[@public is (Postfix[_, @name is Ident()]), @pragma is Pragma()] |
AccQuoted[@name is Ident()] |
(@public is Postfix[_, AccQuoted[@name is Ident()]]) |
PragmaExpr[AccQuoted[@name is Ident()], @pragma is Pragma()] |
PragmaExpr[(@public is Postfix[_, AccQuoted[@name is Ident()]]), @pragma is Pragma()],
@typeNode,
_
]

pragma

func isPublic(identDefs: NimNode): bool =
## Check if the field is public

assertMatch identDefs:
IdentDefs[
(@public is PostFix()) |
Ident() |
PragmaExpr[
(@public is PostFix()) |
Ident(),
_
],
_,
_
]
let typeNodeResult =
case typeNode.kind
# generic
of nnkBracketExpr:
deSymBracketExpr(typeNode)
else:
typeNode

public.isSome
(typeNodeResult, name, pragma, public.isSome)

func deSymBracketExpr(bracket: NimNode): NimNode =
## HACK: https://github.com/nim-lang/Nim/issues/19670
Expand All @@ -352,103 +310,3 @@ func deSymBracketExpr(bracket: NimNode): NimNode =
result.add deSymBracketExpr(i)
else:
result.add i


when isMainModule:
type Test[T] = object

macro run() =
block:
let identDefs = nnkIdentDefs.newTree(
newIdentNode("id"),
newIdentNode("int"),
newEmptyNode()
)

doAssert identDefs.getPragma().isNone

block:
let identDefs = nnkIdentDefs.newTree(
nnkPragmaExpr.newTree(
newIdentNode("id"),
nnkPragma.newTree(
newIdentNode("test")
)
),
newIdentNode("int"),
newEmptyNode()
)

doAssert identDefs.getPragma().get() == nnkPragma.newTree(newIdentNode("test"))

block:
doAssertRaises(AssertionDefect):
discard getPragma(newEmptyNode())

block:
let identDefs = [
nnkIdentDefs.newTree(
newIdentNode("id"),
newIdentNode("int"),
newEmptyNode()
),
nnkIdentDefs.newTree(
nnkPostfix.newTree(
newIdentNode("*"),
newIdentNode("id")
),
newIdentNode("int"),
newEmptyNode()
),
nnkIdentDefs.newTree(
nnkPragmaExpr.newTree(
newIdentNode("id"),
nnkPragma.newTree(
newIdentNode("test")
)
),
newIdentNode("int"),
newEmptyNode()
),
nnkIdentDefs.newTree(
nnkPragmaExpr.newTree(
nnkPostfix.newTree(
newIdentNode("*"),
newIdentNode("id")
),
nnkPragma.newTree(
newIdentNode("test")
)
),
newIdentNode("int"),
newEmptyNode()
)
]

for i in identDefs:
doAssert getNameIdent(i) == ident "id"

block:
let
withGeneric = nnkIdentDefs.newTree(
newIdentNode("id"),
nnkBracketExpr.newTree(
bindSym("Test"),
newIdentNode("T")
),
newEmptyNode()
)
withoutGeneric = nnkIdentDefs.newTree(
newIdentNode("id"),
bindSym("int"),
newEmptyNode()
)

doAssert withGeneric.getType() == nnkBracketExpr.newTree(
bindSym("Test"),
newIdentNode("T")
)

doAssert withoutGeneric.getType() == bindSym("int")

run()
19 changes: 18 additions & 1 deletion tests/des/tmake.nim
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ type
ObjectWithRequiresInit {.requiresInit.} = object
text: string

Quotes = object
`first`: string
`second`*: string
`third` {.skipped.}: string
`fourth`* {.skipped.}: string


proc `==`*(x, y: ObjectWithRef): bool = x.id[] == y.id[]

Expand Down Expand Up @@ -241,7 +247,8 @@ makeDeserializable([
CaseObjectMultiBranch,
AliasesPragma,
AliasesWithRenameAllPragma,
ObjectWithRequiresInit
ObjectWithRequiresInit,
Quotes
], public=true)


Expand Down Expand Up @@ -605,3 +612,13 @@ suite "makeDeserializable":
initStringToken("123"),
initStructEndToken()
]

test "Quotes":
assertDesTokens Quotes(first: "1", second: "2"), [
initStructToken("Quotes", 2),
initStringToken("first"),
initStringToken("1"),
initStringToken("second"),
initStringToken("2"),
initStructEndToken()
]
19 changes: 18 additions & 1 deletion tests/ser/tmake.nim
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ type
first: string
of Third, Fourth:
second: string

Quotes = object
`first`: string
`second`*: string
`third` {.skipped.}: string
`fourth`* {.skipped.}: string


makeSerializable([
Expand All @@ -171,7 +177,8 @@ makeSerializable([
MultiCaseObjectUntagged,
MultiCaseObjectAllUntagged,
RenameWithCase,
CaseObjectMultiBranch
CaseObjectMultiBranch,
Quotes
], public=true)


Expand Down Expand Up @@ -454,3 +461,13 @@ suite "makeSerializable":
assertSerTokens temp2, [
initNoneToken()
]

test "Quotes":
assertSerTokens Quotes(first: "1", second: "2"), [
initMapToken(none int),
initStringToken("first"),
initStringToken("1"),
initStringToken("second"),
initStringToken("2"),
initMapEndToken()
]

0 comments on commit 08144b5

Please sign in to comment.