Cleanup return type open syms (#261)

This commit is contained in:
Tanguy 2022-03-30 15:13:58 +02:00 committed by GitHub
parent 8719723077
commit fc65ff8c5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 5 deletions

View File

@ -72,6 +72,20 @@ proc verifyReturnType(typeName: string) {.compileTime.} =
macro unsupported(s: static[string]): untyped =
error s
proc cleanupOpenSymChoice(node: NimNode): NimNode {.compileTime.} =
# Replace every Call -> OpenSymChoice by a Bracket expr
# ref https://github.com/nim-lang/Nim/issues/11091
if node.kind in nnkCallKinds and
node[0].kind == nnkOpenSymChoice and node[0].eqIdent("[]"):
result = newNimNode(nnkBracketExpr).add(
cleanupOpenSymChoice(node[1]),
cleanupOpenSymChoice(node[2])
)
else:
result = node.copyNimNode()
for child in node:
result.add(cleanupOpenSymChoice(child))
proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
## This macro transforms a single procedure into a closure iterator.
## The ``async`` macro supports a stmtList holding multiple async procedures.
@ -81,17 +95,13 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
let prcName = prc.name.getName
let returnType = prc.params[0]
let returnType = cleanupOpenSymChoice(prc.params[0])
var baseType: NimNode
# Verify that the return type is a Future[T]
if returnType.kind == nnkBracketExpr:
let fut = repr(returnType[0])
verifyReturnType(fut)
baseType = returnType[1]
elif returnType.kind in nnkCallKinds and returnType[0].eqIdent("[]"):
let fut = repr(returnType[1])
verifyReturnType(fut)
baseType = returnType[2]
elif returnType.kind == nnkEmpty:
baseType = returnType
else:

View File

@ -6,6 +6,7 @@
# Apache License, version 2.0, (LICENSE-APACHEv2)
# MIT license (LICENSE-MIT)
import unittest2
import macros
import ../chronos
when defined(nimHasUsed): {.used.}
@ -80,3 +81,19 @@ suite "Macro transformations test suite":
check waitFor(testAwait()) == true
test "`awaitne` command test":
check waitFor(testAwaitne()) == true
test "template async macro transformation":
template templatedAsync(name, restype: untyped): untyped =
proc name(): Future[restype] {.async.} = return @[4]
templatedAsync(testTemplate, seq[int])
check waitFor(testTemplate()) == @[4]
macro macroAsync(name, restype, innerrestype: untyped): untyped =
quote do:
proc `name`(): Future[`restype`[`innerrestype`]] {.async.} = return
type OpenObject = object
macroAsync(testMacro, seq, OpenObject)
check waitFor(testMacro()).len == 0