mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-02 18:07:59 +00:00
Add hasClosure to std/effecttraits
This commit is contained in:
@@ -244,6 +244,8 @@
|
||||
|
||||
- Added dollar `$` and `len` for `jsre.RegExp`.
|
||||
|
||||
- Added `hasClosure` to `std/effecttraits`.
|
||||
|
||||
|
||||
## Language changes
|
||||
|
||||
|
||||
@@ -316,3 +316,7 @@ proc registerAdditionalOps*(c: PCtx) =
|
||||
let fn = getNode(a, 0)
|
||||
setResult(a, (fn.typ != nil and tfNoSideEffect in fn.typ.flags) or
|
||||
(fn.kind == nkSym and fn.sym.kind == skFunc))
|
||||
|
||||
registerCallback c, "stdlib.effecttraits.hasClosureImpl", proc (a: VmArgs) =
|
||||
let fn = getNode(a, 0)
|
||||
setResult(a, fn.kind == nkClosure or (fn.typ != nil and fn.typ.callConv == ccClosure))
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
## One can test for the existance of this standard module
|
||||
## via `defined(nimHasEffectTraitsModule)`.
|
||||
|
||||
import macros
|
||||
import std/macros
|
||||
import std/private/since
|
||||
|
||||
proc getRaisesListImpl(n: NimNode): NimNode = discard "see compiler/vmops.nim"
|
||||
proc getTagsListImpl(n: NimNode): NimNode = discard "see compiler/vmops.nim"
|
||||
proc isGcSafeImpl(n: NimNode): bool = discard "see compiler/vmops.nim"
|
||||
proc hasNoSideEffectsImpl(n: NimNode): bool = discard "see compiler/vmops.nim"
|
||||
proc hasClosureImpl(n: NimNode): bool = discard "see compiler/vmops.nim"
|
||||
|
||||
proc getRaisesList*(fn: NimNode): NimNode =
|
||||
## Extracts the `.raises` list of the func/proc/etc `fn`.
|
||||
@@ -52,3 +54,11 @@ proc hasNoSideEffects*(fn: NimNode): bool =
|
||||
## arguments and not `untyped` arguments.
|
||||
expectKind fn, nnkSym
|
||||
result = hasNoSideEffectsImpl(fn)
|
||||
|
||||
proc hasClosure*(fn: NimNode): bool {.since: (1, 5, 1).} =
|
||||
## Return true if the func/proc/etc `fn` has `closure`.
|
||||
## `fn` has to be a resolved symbol of kind `nnkSym`. This
|
||||
## implies that the macro that calls this proc should accept `typed`
|
||||
## arguments and not `untyped` arguments.
|
||||
expectKind fn, nnkSym
|
||||
result = hasClosureImpl(fn)
|
||||
|
||||
92
tests/stdlib/teffecttraits.nim
Normal file
92
tests/stdlib/teffecttraits.nim
Normal file
@@ -0,0 +1,92 @@
|
||||
discard """
|
||||
targets: "c cpp js"
|
||||
"""
|
||||
|
||||
import std/effecttraits
|
||||
|
||||
|
||||
|
||||
macro testClosure(fn: typed, flag: static bool) =
|
||||
if flag:
|
||||
doAssert hasClosure(fn)
|
||||
else:
|
||||
doAssert not hasClosure(fn)
|
||||
|
||||
block:
|
||||
proc h1() =
|
||||
echo 1
|
||||
|
||||
testClosure(h1, false)
|
||||
|
||||
proc h2() {.nimcall.} =
|
||||
echo 2
|
||||
|
||||
testClosure(h2, false)
|
||||
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
proc hello() {.nimcall.} =
|
||||
echo 3
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, false)
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
proc hello() =
|
||||
echo 3
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, false)
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
var x = 0
|
||||
proc hello() =
|
||||
echo 3
|
||||
inc x
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, true)
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
var x = 0
|
||||
proc hello() {.closure.} =
|
||||
echo 3
|
||||
inc x
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, true)
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
var x = 0
|
||||
proc hello() {.closure.} =
|
||||
echo 3
|
||||
inc x
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, true)
|
||||
|
||||
let name2 = name
|
||||
testClosure(name2, true)
|
||||
|
||||
block:
|
||||
iterator hello(): int =
|
||||
yield 1
|
||||
|
||||
testClosure(hello, false)
|
||||
|
||||
when not defined(js):
|
||||
block:
|
||||
iterator hello(): int {.closure.}=
|
||||
yield 1
|
||||
|
||||
testClosure(hello, true)
|
||||
Reference in New Issue
Block a user