Merge pull request #6944 from alehander42/fix-discardable
Make asyncjs Future[void] play nicely with last line discardable calls & forward declaration
This commit is contained in:
commit
8c0e73479e
2 changed files with 49 additions and 12 deletions
|
|
@ -44,10 +44,10 @@
|
||||||
## resolve(game)
|
## resolve(game)
|
||||||
## return promise
|
## return promise
|
||||||
##
|
##
|
||||||
## Forward definitions work properly, you just don't need to add the ``{.async.}`` pragma:
|
## Forward definitions work properly, you just need to always add the ``{.async.}`` pragma:
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## proc loadGame(name: string): Future[Game]
|
## proc loadGame(name: string): Future[Game] {.async.}
|
||||||
##
|
##
|
||||||
## JavaScript compatibility
|
## JavaScript compatibility
|
||||||
## ~~~~~~~~~~~~~~~~~~~~~~~~~
|
## ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
@ -83,23 +83,54 @@ proc replaceReturn(node: var NimNode) =
|
||||||
replaceReturn(son)
|
replaceReturn(son)
|
||||||
inc z
|
inc z
|
||||||
|
|
||||||
|
proc isFutureVoid(node: NimNode): bool =
|
||||||
|
result = node.kind == nnkBracketExpr and
|
||||||
|
node[0].kind == nnkIdent and $node[0] == "Future" and
|
||||||
|
node[1].kind == nnkIdent and $node[1] == "void"
|
||||||
|
|
||||||
proc generateJsasync(arg: NimNode): NimNode =
|
proc generateJsasync(arg: NimNode): NimNode =
|
||||||
assert arg.kind == nnkProcDef
|
assert arg.kind == nnkProcDef
|
||||||
result = arg
|
result = arg
|
||||||
|
var isVoid = false
|
||||||
|
var jsResolveNode = ident("jsResolve")
|
||||||
|
|
||||||
if arg.params[0].kind == nnkEmpty:
|
if arg.params[0].kind == nnkEmpty:
|
||||||
result.params[0] = nnkBracketExpr.newTree(ident("Future"), ident("void"))
|
result.params[0] = nnkBracketExpr.newTree(ident("Future"), ident("void"))
|
||||||
|
isVoid = true
|
||||||
|
elif isFutureVoid(arg.params[0]):
|
||||||
|
isVoid = true
|
||||||
|
|
||||||
var code = result.body
|
var code = result.body
|
||||||
replaceReturn(code)
|
replaceReturn(code)
|
||||||
result.body = nnkStmtList.newTree()
|
result.body = nnkStmtList.newTree()
|
||||||
var q = quote:
|
|
||||||
proc await[T](f: Future[T]): T {.importcpp: "(await #)".}
|
if len(code) > 0:
|
||||||
proc jsResolve[T](a: T): Future[T] {.importcpp: "#".}
|
var awaitFunction = quote:
|
||||||
result.body.add(q)
|
proc await[T](f: Future[T]): T {.importcpp: "(await #)".}
|
||||||
|
result.body.add(awaitFunction)
|
||||||
|
|
||||||
|
var resolve: NimNode
|
||||||
|
if isVoid:
|
||||||
|
resolve = quote:
|
||||||
|
var `jsResolveNode` {.importcpp: "undefined".}: Future[void]
|
||||||
|
else:
|
||||||
|
resolve = quote:
|
||||||
|
proc jsResolve[T](a: T): Future[T] {.importcpp: "#".}
|
||||||
|
result.body.add(resolve)
|
||||||
|
else:
|
||||||
|
result.body = newEmptyNode()
|
||||||
for child in code:
|
for child in code:
|
||||||
result.body.add(child)
|
result.body.add(child)
|
||||||
|
|
||||||
|
if len(code) > 0 and isVoid:
|
||||||
|
var voidFix = quote:
|
||||||
|
return `jsResolveNode`
|
||||||
|
result.body.add(voidFix)
|
||||||
|
|
||||||
result.pragma = quote:
|
result.pragma = quote:
|
||||||
{.codegenDecl: "async function $2($3)".}
|
{.codegenDecl: "async function $2($3)".}
|
||||||
|
|
||||||
|
|
||||||
macro async*(arg: untyped): untyped =
|
macro async*(arg: untyped): untyped =
|
||||||
## Macro which converts normal procedures into
|
## Macro which converts normal procedures into
|
||||||
## javascript-compatible async procedures
|
## javascript-compatible async procedures
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
discard """
|
discard """
|
||||||
disabled: true
|
disabled: true
|
||||||
output: '''
|
output: '''
|
||||||
0
|
|
||||||
x
|
x
|
||||||
|
e
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -10,16 +10,22 @@ import asyncjs
|
||||||
|
|
||||||
# demonstrate forward definition
|
# demonstrate forward definition
|
||||||
# for js
|
# for js
|
||||||
proc y(e: int): Future[string]
|
proc y(e: int): Future[string] {.async.}
|
||||||
|
|
||||||
proc x(e: int) {.async.} =
|
proc e: int {.discardable.} =
|
||||||
|
echo "e"
|
||||||
|
return 2
|
||||||
|
|
||||||
|
proc x(e: int): Future[void] {.async.} =
|
||||||
var s = await y(e)
|
var s = await y(e)
|
||||||
echo s
|
echo s
|
||||||
|
e()
|
||||||
|
|
||||||
proc y(e: int): Future[string] {.async.} =
|
proc y(e: int): Future[string] {.async.} =
|
||||||
echo 0
|
if e > 0:
|
||||||
return "x"
|
return await y(0)
|
||||||
|
else:
|
||||||
|
return "x"
|
||||||
|
|
||||||
|
|
||||||
discard x(2)
|
discard x(2)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue