nim-chronos/chronos/internal/asyncmacro.nim

591 lines
20 KiB
Nim
Raw Normal View History

2018-05-16 08:22:34 +00:00
#
#
# Nim's Runtime Library
# (c) Copyright 2015 Dominik Picheta
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
# (c) Copyright 2018-Present Status Research & Development GmbH
2018-05-16 08:22:34 +00:00
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
import
std/[macros],
../[futures, config],
./raisesfutures
2018-05-16 08:22:34 +00:00
proc processBody(node, setResultSym: NimNode): NimNode {.compileTime.} =
2018-05-16 08:22:34 +00:00
case node.kind
of nnkReturnStmt:
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
# `return ...` -> `setResult(...); return`
let
res = newNimNode(nnkStmtList, node)
if node[0].kind != nnkEmpty:
res.add newCall(setResultSym, processBody(node[0], setResultSym))
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
res.add newNimNode(nnkReturnStmt, node).add(newEmptyNode())
2018-05-16 08:22:34 +00:00
res
of RoutineNodes-{nnkTemplateDef}:
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
# Skip nested routines since they have their own return value distinct from
# the Future we inject
node
else:
if node.kind == nnkYieldStmt:
# asyncdispatch allows `yield` but this breaks cancellation
warning(
"`yield` in async procedures not supported - use `awaitne` instead",
node)
for i in 0 ..< node.len:
node[i] = processBody(node[i], setResultSym)
node
2018-05-16 08:22:34 +00:00
proc wrapInTryFinally(
fut, baseType, body, raises: NimNode,
handleException: bool): NimNode {.compileTime.} =
# creates:
# try: `body`
# [for raise in raises]:
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
# except `raise`: closureSucceeded = false; `castFutureSym`.fail(exc)
# finally:
# if closureSucceeded:
# `castFutureSym`.complete(result)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
#
# Calling `complete` inside `finally` ensures that all success paths
# (including early returns and code inside nested finally statements and
# defer) are completed with the final contents of `result`
let
closureSucceeded = genSym(nskVar, "closureSucceeded")
nTry = nnkTryStmt.newTree(body)
excName = ident"exc"
# Depending on the exception type, we must have at most one of each of these
# "special" exception handlers that are needed to implement cancellation and
# Defect propagation
var
hasDefect = false
hasCancelledError = false
hasCatchableError = false
template addDefect =
if not hasDefect:
hasDefect = true
# When a Defect is raised, the program is in an undefined state and
# continuing running other tasks while the Future completion sits on the
# callback queue may lead to further damage so we re-raise them eagerly.
nTry.add nnkExceptBranch.newTree(
nnkInfix.newTree(ident"as", ident"Defect", excName),
nnkStmtList.newTree(
nnkAsgn.newTree(closureSucceeded, ident"false"),
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
nnkRaiseStmt.newTree(excName)
)
)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
template addCancelledError =
if not hasCancelledError:
hasCancelledError = true
nTry.add nnkExceptBranch.newTree(
ident"CancelledError",
nnkStmtList.newTree(
nnkAsgn.newTree(closureSucceeded, ident"false"),
newCall(ident "cancelAndSchedule", fut)
)
)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
template addCatchableError =
if not hasCatchableError:
hasCatchableError = true
nTry.add nnkExceptBranch.newTree(
nnkInfix.newTree(ident"as", ident"CatchableError", excName),
nnkStmtList.newTree(
nnkAsgn.newTree(closureSucceeded, ident"false"),
newCall(ident "fail", fut, excName)
))
var raises = if raises == nil:
nnkTupleConstr.newTree(ident"CatchableError")
elif isNoRaises(raises):
nnkTupleConstr.newTree()
else:
raises.copyNimTree()
if handleException:
raises.add(ident"Exception")
for exc in raises:
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
if exc.eqIdent("Exception"):
addCancelledError
addCatchableError
addDefect
# Because we store `CatchableError` in the Future, we cannot re-raise the
# original exception
nTry.add nnkExceptBranch.newTree(
nnkInfix.newTree(ident"as", ident"Exception", excName),
newCall(ident "fail", fut,
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
nnkStmtList.newTree(
nnkAsgn.newTree(closureSucceeded, ident"false"),
quote do:
(ref AsyncExceptionError)(
msg: `excName`.msg, parent: `excName`)))
)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
elif exc.eqIdent("CancelledError"):
addCancelledError
elif exc.eqIdent("CatchableError"):
# Ensure cancellations are re-routed to the cancellation handler even if
# not explicitly specified in the raises list
addCancelledError
addCatchableError
else:
nTry.add nnkExceptBranch.newTree(
nnkInfix.newTree(ident"as", exc, excName),
nnkStmtList.newTree(
nnkAsgn.newTree(closureSucceeded, ident"false"),
newCall(ident "fail", fut, excName)
))
addDefect # Must not complete future on defect
nTry.add nnkFinally.newTree(
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
nnkIfStmt.newTree(
nnkElifBranch.newTree(
closureSucceeded,
if baseType.eqIdent("void"): # shortcut for non-generic void
newCall(ident "complete", fut)
else:
nnkWhenStmt.newTree(
nnkElifExpr.newTree(
nnkInfix.newTree(ident "is", baseType, ident "void"),
newCall(ident "complete", fut)
),
nnkElseExpr.newTree(
newCall(ident "complete", fut, newCall(ident "move", ident "result"))
)
)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
)
)
)
nnkStmtList.newTree(
newVarStmt(closureSucceeded, ident"true"),
nTry
)
2018-05-16 08:22:34 +00:00
proc getName(node: NimNode): string {.compileTime.} =
case node.kind
of nnkSym:
return node.strVal
2018-05-16 08:22:34 +00:00
of nnkPostfix:
return node[1].strVal
of nnkIdent:
return node.strVal
of nnkEmpty:
return "anonymous"
else:
error("Unknown name.")
2019-08-15 16:35:42 +00:00
macro unsupported(s: static[string]): untyped =
error s
proc params2(someProc: NimNode): NimNode {.compileTime.} =
# until https://github.com/nim-lang/Nim/pull/19563 is available
if someProc.kind == nnkProcTy:
someProc[0]
else:
params(someProc)
2022-03-30 13:13:58 +00:00
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)
for child in node[1..^1]:
result.add(cleanupOpenSymChoice(child))
2022-03-30 13:13:58 +00:00
else:
result = node.copyNimNode()
for child in node:
result.add(cleanupOpenSymChoice(child))
type
AsyncParams = tuple
raw: bool
raises: NimNode
handleException: bool
proc decodeParams(params: NimNode): AsyncParams =
# decodes the parameter tuple given in `async: (name: value, ...)` to its
# recognised parts
params.expectKind(nnkTupleConstr)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
var
raw = false
raises: NimNode = nil
handleException = chronosHandleException
for param in params:
param.expectKind(nnkExprColonExpr)
if param[0].eqIdent("raises"):
param[1].expectKind(nnkBracket)
if param[1].len == 0:
raises = makeNoRaises()
else:
raises = nnkTupleConstr.newTree()
for possibleRaise in param[1]:
raises.add(possibleRaise)
elif param[0].eqIdent("raw"):
# boolVal doesn't work in untyped macros it seems..
raw = param[1].eqIdent("true")
elif param[0].eqIdent("handleException"):
handleException = param[1].eqIdent("true")
else:
warning("Unrecognised async parameter: " & repr(param[0]), param)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
(raw, raises, handleException)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
proc isEmpty(n: NimNode): bool {.compileTime.} =
# true iff node recursively contains only comments or empties
case n.kind
of nnkEmpty, nnkCommentStmt: true
of nnkStmtList:
for child in n:
if not isEmpty(child): return false
true
else:
false
proc asyncSingleProc(prc, params: NimNode): NimNode {.compileTime.} =
2018-05-16 08:22:34 +00:00
## This macro transforms a single procedure into a closure iterator.
## The ``async`` macro supports a stmtList holding multiple async procedures.
if prc.kind notin {nnkProcTy, nnkProcDef, nnkLambda, nnkMethodDef, nnkDo}:
error("Cannot transform " & $prc.kind & " into an async proc." &
" proc/method definition or lambda node expected.", prc)
2018-05-16 08:22:34 +00:00
for pragma in prc.pragma():
if pragma.kind == nnkExprColonExpr and pragma[0].eqIdent("raises"):
warning("The raises pragma doesn't work on async procedures - use " &
"`async: (raises: [...]) instead.", prc)
let returnType = cleanupOpenSymChoice(prc.params2[0])
2018-05-16 08:22:34 +00:00
# Verify that the return type is a Future[T]
let baseType =
if returnType.kind == nnkEmpty:
ident "void"
elif not (
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
returnType.kind == nnkBracketExpr and
(eqIdent(returnType[0], "Future") or eqIdent(returnType[0], "InternalRaisesFuture"))):
error(
"Expected return type of 'Future' got '" & repr(returnType) & "'", prc)
return
else:
returnType[1]
2018-05-16 08:22:34 +00:00
let
# When the base type is known to be void (and not generic), we can simplify
# code generation - however, in the case of generic async procedures it
# could still end up being void, meaning void detection needs to happen
# post-macro-expansion.
baseTypeIsVoid = baseType.eqIdent("void")
(raw, raises, handleException) = decodeParams(params)
internalFutureType =
if baseTypeIsVoid:
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
newNimNode(nnkBracketExpr, prc).
add(newIdentNode("Future")).
add(baseType)
else:
returnType
internalReturnType = if raises == nil:
internalFutureType
else:
nnkBracketExpr.newTree(
newIdentNode("InternalRaisesFuture"),
baseType,
raises
)
prc.params2[0] = internalReturnType
2018-05-16 08:22:34 +00:00
if prc.kind notin {nnkProcTy, nnkLambda}:
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
prc.addPragma(newColonExpr(ident "stackTrace", ident "off"))
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
# The proc itself doesn't raise
prc.addPragma(
nnkExprColonExpr.newTree(newIdentNode("raises"), nnkBracket.newTree()))
# `gcsafe` isn't deduced even though we require async code to be gcsafe
# https://github.com/nim-lang/RFCs/issues/435
prc.addPragma(newIdentNode("gcsafe"))
if raw: # raw async = body is left as-is
if raises != nil and prc.kind notin {nnkProcTy, nnkLambda} and not isEmpty(prc.body):
# Inject `raises` type marker that causes `newFuture` to return a raise-
# tracking future instead of an ordinary future:
#
# type InternalRaisesFutureRaises = `raisesTuple`
# `body`
prc.body = nnkStmtList.newTree(
nnkTypeSection.newTree(
nnkTypeDef.newTree(
nnkPragmaExpr.newTree(
ident"InternalRaisesFutureRaises",
nnkPragma.newTree(ident "used")),
newEmptyNode(),
raises,
)
),
prc.body
)
elif prc.kind in {nnkProcDef, nnkLambda, nnkMethodDef, nnkDo} and
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
not isEmpty(prc.body):
let
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
setResultSym = ident "setResult"
procBody = prc.body.processBody(setResultSym)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
resultIdent = ident "result"
fakeResult = quote do:
template result: auto {.used.} =
{.fatal: "You should not reference the `result` variable inside" &
" a void async proc".}
resultDecl =
if baseTypeIsVoid: fakeResult
else: nnkWhenStmt.newTree(
# when `baseType` is void:
nnkElifExpr.newTree(
nnkInfix.newTree(ident "is", baseType, ident "void"),
fakeResult
),
# else:
nnkElseExpr.newTree(
newStmtList(
quote do: {.push warning[resultshadowed]: off.},
# var result {.used.}: `baseType`
# In the proc body, result may or may not end up being used
# depending on how the body is written - with implicit returns /
# expressions in particular, it is likely but not guaranteed that
# it is not used. Ideally, we would avoid emitting it in this
# case to avoid the default initializaiton. {.used.} typically
# works better than {.push.} which has a tendency to leak out of
# scope.
# TODO figure out if there's a way to detect `result` usage in
# the proc body _after_ template exapnsion, and therefore
# avoid creating this variable - one option is to create an
# addtional when branch witha fake `result` and check
# `compiles(procBody)` - this is not without cost though
nnkVarSection.newTree(nnkIdentDefs.newTree(
nnkPragmaExpr.newTree(
resultIdent,
nnkPragma.newTree(ident "used")),
baseType, newEmptyNode())
),
quote do: {.pop.},
)
)
)
# ```nim
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
# template `setResultSym`(code: untyped) {.used.} =
# when typeof(code) is void: code
# else: `resultIdent` = code
# ```
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
#
# this is useful to handle implicit returns, but also
# to bind the `result` to the one we declare here
setResultDecl =
if baseTypeIsVoid: # shortcut for non-generic void
newEmptyNode()
else:
nnkTemplateDef.newTree(
setResultSym,
newEmptyNode(), newEmptyNode(),
nnkFormalParams.newTree(
newEmptyNode(),
nnkIdentDefs.newTree(
ident"code",
ident"untyped",
newEmptyNode(),
)
),
nnkPragma.newTree(ident"used"),
newEmptyNode(),
nnkWhenStmt.newTree(
nnkElifBranch.newTree(
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
nnkInfix.newTree(
ident"is", nnkTypeOfExpr.newTree(ident"code"), ident"void"),
ident"code"
),
nnkElse.newTree(
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
newAssignment(resultIdent, ident"code")
)
)
)
internalFutureSym = ident "chronosInternalRetFuture"
castFutureSym = nnkCast.newTree(internalFutureType, internalFutureSym)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
# Wrapping in try/finally ensures that early returns are handled properly
# and that `defer` is processed in the right scope
completeDecl = wrapInTryFinally(
castFutureSym, baseType,
if baseTypeIsVoid: procBody # shortcut for non-generic `void`
else: newCall(setResultSym, procBody),
raises,
handleException
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
closureBody = newStmtList(resultDecl, setResultDecl, completeDecl)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
internalFutureParameter = nnkIdentDefs.newTree(
internalFutureSym, newIdentNode("FutureBase"), newEmptyNode())
prcName = prc.name.getName
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
iteratorNameSym = genSym(nskIterator, $prcName)
closureIterator = newProc(
iteratorNameSym,
[newIdentNode("FutureBase"), internalFutureParameter],
closureBody, nnkIteratorDef)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
iteratorNameSym.copyLineInfo(prc)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
closureIterator.pragma = newNimNode(nnkPragma, lineInfoFrom=prc.body)
closureIterator.addPragma(newIdentNode("closure"))
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
# `async` code must be gcsafe
closureIterator.addPragma(newIdentNode("gcsafe"))
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
# Exceptions are caught inside the iterator and stored in the future
closureIterator.addPragma(nnkExprColonExpr.newTree(
newIdentNode("raises"),
nnkBracket.newTree()
))
# The body of the original procedure (now moved to the iterator) is replaced
# with:
#
# ```nim
# let resultFuture = newFuture[T]()
# resultFuture.internalClosure = `iteratorNameSym`
# futureContinue(resultFuture)
# return resultFuture
# ```
#
# Declared at the end to be sure that the closure doesn't reference it,
# avoid cyclic ref (#203)
#
# Do not change this code to `quote do` version because `instantiationInfo`
# will be broken for `newFuture()` call.
let
outerProcBody = newNimNode(nnkStmtList, prc.body)
# Copy comment for nimdoc
if prc.body.len > 0 and prc.body[0].kind == nnkCommentStmt:
outerProcBody.add(prc.body[0])
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
outerProcBody.add(closureIterator)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
let
retFutureSym = ident "resultFuture"
newFutProc = if raises == nil:
nnkBracketExpr.newTree(ident "newFuture", baseType)
else:
nnkBracketExpr.newTree(ident "newInternalRaisesFuture", baseType, raises)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
retFutureSym.copyLineInfo(prc)
outerProcBody.add(
newLetStmt(
retFutureSym,
newCall(newFutProc, newLit(prcName))
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
)
)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
outerProcBody.add(
newAssignment(
newDotExpr(retFutureSym, newIdentNode("internalClosure")),
iteratorNameSym)
)
2019-08-15 16:35:42 +00:00
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
outerProcBody.add(
newCall(newIdentNode("futureContinue"), retFutureSym)
)
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
outerProcBody.add newNimNode(nnkReturnStmt, prc.body[^1]).add(retFutureSym)
2018-05-16 08:22:34 +00:00
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
prc.body = outerProcBody
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
when chronosDumpAsync:
echo repr prc
prc
2018-05-16 08:22:34 +00:00
template await*[T](f: Future[T]): T =
## Ensure that the given `Future` is finished, then return its value.
##
## If the `Future` failed or was cancelled, the corresponding exception will
## be raised instead.
##
## If the `Future` is pending, execution of the current `async` procedure
## will be suspended until the `Future` is finished.
2019-08-15 13:32:46 +00:00
when declared(chronosInternalRetFuture):
chronosInternalRetFuture.internalChild = f
# `futureContinue` calls the iterator generated by the `async`
# transformation - `yield` gives control back to `futureContinue` which is
# responsible for resuming execution once the yielded future is finished
yield chronosInternalRetFuture.internalChild
# `child` released by `futureContinue`
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
cast[type(f)](chronosInternalRetFuture.internalChild).internalCheckComplete()
exception tracking (#166) * exception tracking This PR adds minimal exception tracking to chronos, moving the goalpost one step further. In particular, it becomes invalid to raise exceptions from `callSoon` callbacks: this is critical for writing correct error handling because there's no reasonable way that a user of chronos can possibly _reason_ about exceptions coming out of there: the event loop will be in an indeterminite state when the loop is executing an _random_ callback. As expected, there are several issues in the error handling of chronos: in particular, it will end up in an inconsistent internal state whenever the selector loop operations fail, because the internal state update functions are not written in an exception-safe way. This PR turns this into a Defect, which probably is not the optimal way of handling things - expect more work to be done here. Some API have no way of reporting back errors to callers - for example, when something fails in the accept loop, there's not much it can do, and no way to report it back to the user of the API - this has been fixed with the new accept flow - the old one should be deprecated. Finally, there is information loss in the API: in composite operations like `poll` and `waitFor` there's no way to differentiate internal errors from user-level errors originating from callbacks. * store `CatchableError` in future * annotate proc's with correct raises information * `selectors2` to avoid non-CatchableError IOSelectorsException * `$` should never raise * remove unnecessary gcsafe annotations * fix exceptions leaking out of timer waits * fix some imports * functions must signal raising the union of all exceptions across all platforms to enable cross-platform code * switch to unittest2 * add `selectors2` which supercedes the std library version and fixes several exception handling issues in there * fixes * docs, platform-independent eh specifiers for some functions * add feature flag for strict exception mode also bump version to 3.0.0 - _most_ existing code should be compatible with this version of exception handling but some things might need fixing - callbacks, existing raises specifications etc. * fix AsyncCheck for non-void T
2021-03-24 09:08:33 +00:00
when T isnot void:
cast[type(f)](chronosInternalRetFuture.internalChild).value()
2019-08-15 13:32:46 +00:00
else:
2019-08-15 16:35:42 +00:00
unsupported "await is only available within {.async.}"
template await*[T, E](fut: InternalRaisesFuture[T, E]): T =
## Ensure that the given `Future` is finished, then return its value.
##
## If the `Future` failed or was cancelled, the corresponding exception will
## be raised instead.
##
## If the `Future` is pending, execution of the current `async` procedure
## will be suspended until the `Future` is finished.
when declared(chronosInternalRetFuture):
chronosInternalRetFuture.internalChild = fut
# `futureContinue` calls the iterator generated by the `async`
# transformation - `yield` gives control back to `futureContinue` which is
# responsible for resuming execution once the yielded future is finished
yield chronosInternalRetFuture.internalChild
# `child` released by `futureContinue`
cast[type(fut)](
chronosInternalRetFuture.internalChild).internalCheckComplete(E)
when T isnot void:
cast[type(fut)](chronosInternalRetFuture.internalChild).value()
else:
unsupported "await is only available within {.async.}"
2019-08-15 13:32:46 +00:00
template awaitne*[T](f: Future[T]): Future[T] =
when declared(chronosInternalRetFuture):
chronosInternalRetFuture.internalChild = f
yield chronosInternalRetFuture.internalChild
cast[type(f)](chronosInternalRetFuture.internalChild)
2019-08-15 13:32:46 +00:00
else:
2019-08-15 16:35:42 +00:00
unsupported "awaitne is only available within {.async.}"
macro async*(params, prc: untyped): untyped =
2018-05-16 08:22:34 +00:00
## Macro which processes async procedures into the appropriate
## iterators and yield statements.
if prc.kind == nnkStmtList:
result = newStmtList()
2018-05-16 08:22:34 +00:00
for oneProc in prc:
result.add asyncSingleProc(oneProc, params)
2018-05-16 08:22:34 +00:00
else:
result = asyncSingleProc(prc, params)
macro async*(prc: untyped): untyped =
## Macro which processes async procedures into the appropriate
## iterators and yield statements.
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
if prc.kind == nnkStmtList:
result = newStmtList()
for oneProc in prc:
result.add asyncSingleProc(oneProc, nnkTupleConstr.newTree())
Raise tracking (#251) * Exception tracking v2 * some fixes * Nim 1.2 compat * simpler things * Fixes for libp2p * Fixes for strictException * better await exception check * Fix for template async proc * make async work with procTy * FuturEx is now a ref object type * add tests * update test * update readme * Switch to asyncraises pragma * Address tests review comments * Rename FuturEx to RaiseTrackingFuture * Fix typo * Split asyncraises into async, asyncraises * Add -d:chronosWarnMissingRaises * Add comment to RaiseTrackingFuture * Allow standalone asyncraises * CheckedFuture.fail type checking * First cleanup * Remove useless line * Review comments * nimble: Remove #head from unittest2 * Remove implict raises: CancelledError * Move checkFutureExceptions to asyncfutures2 * Small refacto * small cleanup * Complete in closure finally * cleanup tests, add comment * bump * chronos is not compatible with nim 1.2 anymore * re-add readme modifications * fix special exception handlers * also propagate excetion type in `read` * `RaiseTrackingFuture` -> `InternalRaisesFuture` Use internal naming scheme for RTF (this type should only be accessed via asyncraises) * use `internalError` for error reading * oops * 2.0 workarounds * again * remove try/finally for non-raising functions * Revert "remove try/finally for non-raising functions" This reverts commit 86bfeb5c972ef379a3bd34e4a16cd158a7455721. `finally` is needed if code returns early :/ * fixes * avoid exposing `newInternalRaisesFuture` in manual macro code * avoid unnecessary codegen for `Future[void]` * avoid reduntant block around async proc body * simplify body generation for forward declarations with comment but no body * avoid duplicate `gcsafe` annotiations * line info for return at end of async proc * expand tests * fix comments, add defer test --------- Co-authored-by: Jacek Sieka <jacek@status.im>
2023-10-17 12:18:14 +00:00
else:
result = asyncSingleProc(prc, nnkTupleConstr.newTree())