[backport] run nimpretty on async

This commit is contained in:
narimiran 2019-09-27 10:50:16 +02:00
commit aa513d78e7
8 changed files with 61 additions and 57 deletions

View file

@ -236,7 +236,7 @@ when defined(windows) or defined(nimdoc):
CompletionKey = ULONG_PTR CompletionKey = ULONG_PTR
CompletionData* = object CompletionData* = object
fd*: AsyncFD # TODO: Rename this. fd*: AsyncFD # TODO: Rename this.
cb*: owned(proc (fd: AsyncFD, bytesTransferred: DWORD, cb*: owned(proc (fd: AsyncFD, bytesTransferred: DWORD,
errcode: OSErrorCode) {.closure, gcsafe.}) errcode: OSErrorCode) {.closure, gcsafe.})
cell*: ForeignCell # we need this `cell` to protect our `cb` environment, cell*: ForeignCell # we need this `cell` to protect our `cb` environment,
@ -267,7 +267,7 @@ when defined(windows) or defined(nimdoc):
pcd: PostCallbackDataPtr pcd: PostCallbackDataPtr
AsyncEvent* = ptr AsyncEventImpl AsyncEvent* = ptr AsyncEventImpl
Callback = proc (fd: AsyncFD): bool {.closure,gcsafe.} Callback = proc (fd: AsyncFD): bool {.closure, gcsafe.}
proc hash(x: AsyncFD): Hash {.borrow.} proc hash(x: AsyncFD): Hash {.borrow.}
proc `==`*(x: AsyncFD, y: AsyncFD): bool {.borrow.} proc `==`*(x: AsyncFD, y: AsyncFD): bool {.borrow.}
@ -795,7 +795,7 @@ when defined(windows) or defined(nimdoc):
proc contains*(disp: PDispatcher, fd: AsyncFD): bool = proc contains*(disp: PDispatcher, fd: AsyncFD): bool =
return fd in disp.handles return fd in disp.handles
{.push stackTrace:off.} {.push stackTrace: off.}
proc waitableCallback(param: pointer, proc waitableCallback(param: pointer,
timerOrWaitFired: WINBOOL): void {.stdcall.} = timerOrWaitFired: WINBOOL): void {.stdcall.} =
var p = cast[PostCallbackDataPtr](param) var p = cast[PostCallbackDataPtr](param)
@ -953,10 +953,10 @@ when defined(windows) or defined(nimdoc):
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
p.handles.excl(fd) p.handles.excl(fd)
if unregisterWait(waitFd) == 0: if unregisterWait(waitFd) == 0:
let err = osLastError() let err = osLastError()
if err.int32 != ERROR_IO_PENDING: if err.int32 != ERROR_IO_PENDING:
discard closeHandle(handle) discard closeHandle(handle)
raiseOSError(err) raiseOSError(err)
if closeHandle(handle) == 0: if closeHandle(handle) == 0:
raiseOSError(osLastError()) raiseOSError(osLastError())
@ -1093,7 +1093,7 @@ else:
# queue. # queue.
type type
AsyncFD* = distinct cint AsyncFD* = distinct cint
Callback = proc (fd: AsyncFD): bool {.closure,gcsafe.} Callback = proc (fd: AsyncFD): bool {.closure, gcsafe.}
AsyncData = object AsyncData = object
readList: seq[Callback] readList: seq[Callback]
@ -1588,7 +1588,7 @@ proc createAsyncNativeSocket*(domain: Domain = Domain.AF_INET,
createAsyncNativeSocketImpl(domain, sockType, protocol) createAsyncNativeSocketImpl(domain, sockType, protocol)
proc newAsyncNativeSocket*(domain: cint, sockType: cint, proc newAsyncNativeSocket*(domain: cint, sockType: cint,
protocol: cint): AsyncFD {.deprecated: "use createAsyncNativeSocket instead".} = protocol: cint): AsyncFD {.deprecated: "use createAsyncNativeSocket instead".} =
createAsyncNativeSocketImpl(domain, sockType, protocol) createAsyncNativeSocketImpl(domain, sockType, protocol)
proc newAsyncNativeSocket*(domain: Domain = Domain.AF_INET, proc newAsyncNativeSocket*(domain: Domain = Domain.AF_INET,

View file

@ -488,7 +488,7 @@ proc setFileSize*(f: AsyncFile, length: int64) =
status = setFilePointer(f.fd.Handle, low, addr high, 0) status = setFilePointer(f.fd.Handle, low, addr high, 0)
lastErr = osLastError() lastErr = osLastError()
if (status == INVALID_SET_FILE_POINTER and lastErr.int32 != NO_ERROR) or if (status == INVALID_SET_FILE_POINTER and lastErr.int32 != NO_ERROR) or
(setEndOfFile(f.fd.Handle) == 0): (setEndOfFile(f.fd.Handle) == 0):
raiseOSError(osLastError()) raiseOSError(osLastError())
else: else:
# will truncate if Off is a 32-bit type! # will truncate if Off is a 32-bit type!

View file

@ -100,27 +100,27 @@ type
of JRetr, JStore: of JRetr, JStore:
file: File file: File
filename: string filename: string
total: BiggestInt # In bytes. total: BiggestInt # In bytes.
progress: BiggestInt # In bytes. progress: BiggestInt # In bytes.
oneSecond: BiggestInt # Bytes transferred in one second. oneSecond: BiggestInt # Bytes transferred in one second.
lastProgressReport: float # Time lastProgressReport: float # Time
toStore: string # Data left to upload (Only used with async) toStore: string # Data left to upload (Only used with async)
FtpEventType* = enum FtpEventType* = enum
EvTransferProgress, EvLines, EvRetr, EvStore EvTransferProgress, EvLines, EvRetr, EvStore
FtpEvent* = object ## Event FtpEvent* = object ## Event
filename*: string filename*: string
case typ*: FtpEventType case typ*: FtpEventType
of EvLines: of EvLines:
lines*: string ## Lines that have been transferred. lines*: string ## Lines that have been transferred.
of EvRetr, EvStore: ## Retr/Store operation finished. of EvRetr, EvStore: ## Retr/Store operation finished.
nil nil
of EvTransferProgress: of EvTransferProgress:
bytesTotal*: BiggestInt ## Bytes total. bytesTotal*: BiggestInt ## Bytes total.
bytesFinished*: BiggestInt ## Bytes transferred. bytesFinished*: BiggestInt ## Bytes transferred.
speed*: BiggestInt ## Speed in bytes/s speed*: BiggestInt ## Speed in bytes/s
currentJob*: FtpJobType ## The current job being performed. currentJob*: FtpJobType ## The current job being performed.
ReplyError* = object of IOError ReplyError* = object of IOError
@ -154,7 +154,7 @@ proc assertReply(received: TaintedString, expected: varargs[string]) =
if received.string.startsWith(i): return if received.string.startsWith(i): return
raise newException(ReplyError, raise newException(ReplyError,
"Expected reply '$1' got: $2" % "Expected reply '$1' got: $2" %
[expected.join("' or '"), received.string]) [expected.join("' or '"), received.string])
proc pasv(ftp: AsyncFtpClient) {.async.} = proc pasv(ftp: AsyncFtpClient) {.async.} =
## Negotiate a data connection. ## Negotiate a data connection.
@ -164,8 +164,8 @@ proc pasv(ftp: AsyncFtpClient) {.async.} =
assertReply(pasvMsg, "227") assertReply(pasvMsg, "227")
var betweenParens = captureBetween(pasvMsg.string, '(', ')') var betweenParens = captureBetween(pasvMsg.string, '(', ')')
var nums = betweenParens.split(',') var nums = betweenParens.split(',')
var ip = nums[0.. ^3] var ip = nums[0 .. ^3]
var port = nums[^2.. ^1] var port = nums[^2 .. ^1]
var properPort = port[0].parseInt()*256+port[1].parseInt() var properPort = port[0].parseInt()*256+port[1].parseInt()
await ftp.dsock.connect(ip.join("."), Port(properPort.toU16)) await ftp.dsock.connect(ip.join("."), Port(properPort.toU16))
ftp.dsockConnected = true ftp.dsockConnected = true

View file

@ -17,11 +17,11 @@ type
function: CallbackFunc function: CallbackFunc
next: owned(ref CallbackList) next: owned(ref CallbackList)
FutureBase* = ref object of RootObj ## Untyped future. FutureBase* = ref object of RootObj ## Untyped future.
callbacks: CallbackList callbacks: CallbackList
finished: bool finished: bool
error*: ref Exception ## Stored exception error*: ref Exception ## Stored exception
errorStackTrace*: string errorStackTrace*: string
when not defined(release): when not defined(release):
stackTrace: seq[StackTraceEntry] ## For debugging purposes only. stackTrace: seq[StackTraceEntry] ## For debugging purposes only.
@ -29,7 +29,7 @@ type
fromProc: string fromProc: string
Future*[T] = ref object of FutureBase ## Typed future. Future*[T] = ref object of FutureBase ## Typed future.
value: T ## Stored value value: T ## Stored value
FutureVar*[T] = distinct Future[T] FutureVar*[T] = distinct Future[T]
@ -260,7 +260,7 @@ proc clearCallbacks*(future: FutureBase) =
future.callbacks.function = nil future.callbacks.function = nil
future.callbacks.next = nil future.callbacks.next = nil
proc addCallback*(future: FutureBase, cb: proc() {.closure,gcsafe.}) = proc addCallback*(future: FutureBase, cb: proc() {.closure, gcsafe.}) =
## Adds the callbacks proc to be called when the future completes. ## Adds the callbacks proc to be called when the future completes.
## ##
## If future has already completed then ``cb`` will be called immediately. ## If future has already completed then ``cb`` will be called immediately.
@ -271,16 +271,16 @@ proc addCallback*(future: FutureBase, cb: proc() {.closure,gcsafe.}) =
future.callbacks.add cb future.callbacks.add cb
proc addCallback*[T](future: Future[T], proc addCallback*[T](future: Future[T],
cb: proc (future: Future[T]) {.closure,gcsafe.}) = cb: proc (future: Future[T]) {.closure, gcsafe.}) =
## Adds the callbacks proc to be called when the future completes. ## Adds the callbacks proc to be called when the future completes.
## ##
## If future has already completed then ``cb`` will be called immediately. ## If future has already completed then ``cb`` will be called immediately.
future.addCallback( future.addCallback(
proc() = proc() =
cb(future) cb(future)
) )
proc `callback=`*(future: FutureBase, cb: proc () {.closure,gcsafe.}) = proc `callback=`*(future: FutureBase, cb: proc () {.closure, gcsafe.}) =
## Clears the list of callbacks and sets the callback proc to be called when the future completes. ## Clears the list of callbacks and sets the callback proc to be called when the future completes.
## ##
## If future has already completed then ``cb`` will be called immediately. ## If future has already completed then ``cb`` will be called immediately.
@ -290,7 +290,7 @@ proc `callback=`*(future: FutureBase, cb: proc () {.closure,gcsafe.}) =
future.addCallback cb future.addCallback cb
proc `callback=`*[T](future: Future[T], proc `callback=`*[T](future: Future[T],
cb: proc (future: Future[T]) {.closure,gcsafe.}) = cb: proc (future: Future[T]) {.closure, gcsafe.}) =
## Sets the callback proc to be called when the future completes. ## Sets the callback proc to be called when the future completes.
## ##
## If future has already completed then ``cb`` will be called immediately. ## If future has already completed then ``cb`` will be called immediately.

View file

@ -50,7 +50,7 @@ type
headers*: HttpHeaders headers*: HttpHeaders
protocol*: tuple[orig: string, major, minor: int] protocol*: tuple[orig: string, major, minor: int]
url*: Uri url*: Uri
hostname*: string ## The hostname of the client that made the request. hostname*: string ## The hostname of the client that made the request.
body*: string body*: string
AsyncHttpServer* = ref object AsyncHttpServer* = ref object
@ -169,7 +169,7 @@ proc processRequest(
for i in 0..1: for i in 0..1:
lineFut.mget().setLen(0) lineFut.mget().setLen(0)
lineFut.clean() lineFut.clean()
await client.recvLineInto(lineFut, maxLength=maxLine) # TODO: Timeouts. await client.recvLineInto(lineFut, maxLength = maxLine) # TODO: Timeouts.
if lineFut.mget == "": if lineFut.mget == "":
client.close() client.close()
@ -214,7 +214,7 @@ proc processRequest(
i = 0 i = 0
lineFut.mget.setLen(0) lineFut.mget.setLen(0)
lineFut.clean() lineFut.clean()
await client.recvLineInto(lineFut, maxLength=maxLine) await client.recvLineInto(lineFut, maxLength = maxLine)
if lineFut.mget == "": if lineFut.mget == "":
client.close(); return false client.close(); return false
@ -242,7 +242,8 @@ proc processRequest(
# - Check for Content-length header # - Check for Content-length header
if request.headers.hasKey("Content-Length"): if request.headers.hasKey("Content-Length"):
var contentLength = 0 var contentLength = 0
if parseSaturatedNatural(request.headers["Content-Length"], contentLength) == 0: if parseSaturatedNatural(request.headers["Content-Length"],
contentLength) == 0:
await request.respond(Http400, "Bad Request. Invalid Content-Length.") await request.respond(Http400, "Bad Request. Invalid Content-Length.")
return true return true
else: else:

View file

@ -163,7 +163,8 @@ proc processBody(node, retFutureSym: NimNode,
if node[1][0].eqIdent("await"): if node[1][0].eqIdent("await"):
# x = await y # x = await y
var newAsgn = node var newAsgn = node
result.createVar("future" & $node[0].toStrLit, node[1][1], newAsgn[1], newAsgn, node) result.createVar("future" & $node[0].toStrLit, node[1][1], newAsgn[1],
newAsgn, node)
else: discard else: discard
of nnkDiscardStmt: of nnkDiscardStmt:
# discard await x # discard await x
@ -212,8 +213,8 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
## This macro transforms a single procedure into a closure iterator. ## This macro transforms a single procedure into a closure iterator.
## The ``async`` macro supports a stmtList holding multiple async procedures. ## The ``async`` macro supports a stmtList holding multiple async procedures.
if prc.kind notin {nnkProcDef, nnkLambda, nnkMethodDef, nnkDo}: if prc.kind notin {nnkProcDef, nnkLambda, nnkMethodDef, nnkDo}:
error("Cannot transform this node kind into an async proc." & error("Cannot transform this node kind into an async proc." &
" proc/method definition or lambda node expected.") " proc/method definition or lambda node expected.")
let prcName = prc.name.getName let prcName = prc.name.getName
@ -296,11 +297,12 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
var closureIterator = newProc(iteratorNameSym, [parseExpr("owned(FutureBase)")], var closureIterator = newProc(iteratorNameSym, [parseExpr("owned(FutureBase)")],
procBody, nnkIteratorDef) procBody, nnkIteratorDef)
closureIterator.pragma = newNimNode(nnkPragma, lineInfoFrom=prc.body) closureIterator.pragma = newNimNode(nnkPragma, lineInfoFrom = prc.body)
closureIterator.addPragma(newIdentNode("closure")) closureIterator.addPragma(newIdentNode("closure"))
# If proc has an explicit gcsafe pragma, we add it to iterator as well. # If proc has an explicit gcsafe pragma, we add it to iterator as well.
if prc.pragma.findChild(it.kind in {nnkSym, nnkIdent} and $it == "gcsafe") != nil: if prc.pragma.findChild(it.kind in {nnkSym, nnkIdent} and $it ==
"gcsafe") != nil:
closureIterator.addPragma(newIdentNode("gcsafe")) closureIterator.addPragma(newIdentNode("gcsafe"))
outerProcBody.add(closureIterator) outerProcBody.add(closureIterator)
@ -414,20 +416,20 @@ proc splitProc(prc: NimNode): (NimNode, NimNode) =
result[0] = prc.copyNimTree() result[0] = prc.copyNimTree()
# Retrieve the `T` inside `Future[T]`. # Retrieve the `T` inside `Future[T]`.
let returnType = stripReturnType(result[0][3][0]) let returnType = stripReturnType(result[0][3][0])
result[0][3][0] = splitParamType(returnType, async=false) result[0][3][0] = splitParamType(returnType, async = false)
for i in 1 ..< result[0][3].len: for i in 1 ..< result[0][3].len:
# Sync proc (0) -> FormalParams (3) -> IdentDefs, the parameter (i) -> # Sync proc (0) -> FormalParams (3) -> IdentDefs, the parameter (i) ->
# parameter type (1). # parameter type (1).
result[0][3][i][1] = splitParamType(result[0][3][i][1], async=false) result[0][3][i][1] = splitParamType(result[0][3][i][1], async = false)
result[0][6] = stripAwait(result[0][6]) result[0][6] = stripAwait(result[0][6])
result[1] = prc.copyNimTree() result[1] = prc.copyNimTree()
if result[1][3][0].kind == nnkBracketExpr: if result[1][3][0].kind == nnkBracketExpr:
result[1][3][0][1] = splitParamType(result[1][3][0][1], async=true) result[1][3][0][1] = splitParamType(result[1][3][0][1], async = true)
for i in 1 ..< result[1][3].len: for i in 1 ..< result[1][3].len:
# Async proc (1) -> FormalParams (3) -> IdentDefs, the parameter (i) -> # Async proc (1) -> FormalParams (3) -> IdentDefs, the parameter (i) ->
# parameter type (1). # parameter type (1).
result[1][3][i][1] = splitParamType(result[1][3][i][1], async=true) result[1][3][i][1] = splitParamType(result[1][3][i][1], async = true)
macro multisync*(prc: untyped): untyped = macro multisync*(prc: untyped): untyped =
## Macro which processes async procedures into both asynchronous and ## Macro which processes async procedures into both asynchronous and

View file

@ -114,11 +114,11 @@ type
# AsyncSocket* {.borrow: `.`.} = distinct Socket. But that doesn't work. # AsyncSocket* {.borrow: `.`.} = distinct Socket. But that doesn't work.
AsyncSocketDesc = object AsyncSocketDesc = object
fd: SocketHandle fd: SocketHandle
closed: bool ## determines whether this socket has been closed closed: bool ## determines whether this socket has been closed
isBuffered: bool ## determines whether this socket is buffered. isBuffered: bool ## determines whether this socket is buffered.
buffer: array[0..BufferSize, char] buffer: array[0..BufferSize, char]
currPos: int # current index in buffer currPos: int # current index in buffer
bufLen: int # current length of buffer bufLen: int # current length of buffer
isSsl: bool isSsl: bool
when defineSsl: when defineSsl:
sslHandle: SslPtr sslHandle: SslPtr
@ -603,7 +603,8 @@ proc recvLine*(socket: AsyncSocket,
await socket.recvLineInto(resString, flags, maxLength) await socket.recvLineInto(resString, flags, maxLength)
result = resString.mget() result = resString.mget()
proc listen*(socket: AsyncSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = proc listen*(socket: AsyncSocket, backlog = SOMAXCONN) {.tags: [
ReadIOEffect].} =
## Marks ``socket`` as accepting connections. ## Marks ``socket`` as accepting connections.
## ``Backlog`` specifies the maximum length of the ## ``Backlog`` specifies the maximum length of the
## queue of pending connections. ## queue of pending connections.
@ -620,7 +621,7 @@ proc bindAddr*(socket: AsyncSocket, port = Port(0), address = "") {.
if realaddr == "": if realaddr == "":
case socket.domain case socket.domain
of AF_INET6: realaddr = "::" of AF_INET6: realaddr = "::"
of AF_INET: realaddr = "0.0.0.0" of AF_INET: realaddr = "0.0.0.0"
else: else:
raise newException(ValueError, raise newException(ValueError,
"Unknown socket address family and no address specified to bindAddr") "Unknown socket address family and no address specified to bindAddr")
@ -653,7 +654,7 @@ when defined(posix):
var socketAddr = makeUnixAddr(path) var socketAddr = makeUnixAddr(path)
let ret = socket.fd.connect(cast[ptr SockAddr](addr socketAddr), let ret = socket.fd.connect(cast[ptr SockAddr](addr socketAddr),
(sizeof(socketAddr.sun_family) + path.len).SockLen) (sizeof(socketAddr.sun_family) + path.len).SockLen)
if ret == 0: if ret == 0:
# Request to connect completed immediately. # Request to connect completed immediately.
retFuture.complete() retFuture.complete()
@ -671,7 +672,7 @@ when defined(posix):
when not defined(nimdoc): when not defined(nimdoc):
var socketAddr = makeUnixAddr(path) var socketAddr = makeUnixAddr(path)
if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr), if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr),
(sizeof(socketAddr.sun_family) + path.len).SockLen) != 0'i32: (sizeof(socketAddr.sun_family) + path.len).SockLen) != 0'i32:
raiseOSError(osLastError()) raiseOSError(osLastError())
elif defined(nimdoc): elif defined(nimdoc):

View file

@ -14,10 +14,10 @@ import asyncfutures
import deques import deques
type type
FutureStream*[T] = ref object ## Special future that acts as FutureStream*[T] = ref object ## Special future that acts as
## a queue. Its API is still ## a queue. Its API is still
## experimental and so is ## experimental and so is
## subject to change. ## subject to change.
queue: Deque[T] queue: Deque[T]
finished: bool finished: bool
cb: proc () {.closure, gcsafe.} cb: proc () {.closure, gcsafe.}
@ -45,7 +45,7 @@ proc complete*[T](future: FutureStream[T]) =
future.cb() future.cb()
proc `callback=`*[T](future: FutureStream[T], proc `callback=`*[T](future: FutureStream[T],
cb: proc (future: FutureStream[T]) {.closure,gcsafe.}) = cb: proc (future: FutureStream[T]) {.closure, gcsafe.}) =
## Sets the callback proc to be called when data was placed inside the ## Sets the callback proc to be called when data was placed inside the
## future stream. ## future stream.
## ##