importjs symbol (#12218)
* importjs symbol * importjs warning message, minor warning fixes
This commit is contained in:
parent
7bc5bf8334
commit
38ab51c445
7 changed files with 388 additions and 24 deletions
|
|
@ -75,12 +75,15 @@ iterator myitems[T](x: openarray[T]): lent T
|
||||||
iterator mypairs[T](x: openarray[T]): tuple[idx: int, val: lent T]
|
iterator mypairs[T](x: openarray[T]): tuple[idx: int, val: lent T]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `importjs` can now be used to import for ffi on the JS target
|
||||||
|
|
||||||
## Language changes
|
## Language changes
|
||||||
|
|
||||||
- `uint64` is now finally a regular ordinal type. This means `high(uint64)` compiles
|
- `uint64` is now finally a regular ordinal type. This means `high(uint64)` compiles
|
||||||
and yields the correct value.
|
and yields the correct value.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Tool changes
|
### Tool changes
|
||||||
|
|
||||||
- The Nim compiler now does not recompile the Nim project via ``nim c -r`` if
|
- The Nim compiler now does not recompile the Nim project via ``nim c -r`` if
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const
|
||||||
LastCallConv* = wNoconv
|
LastCallConv* = wNoconv
|
||||||
|
|
||||||
const
|
const
|
||||||
declPragmas = {wImportc, wImportObjC, wImportCpp, wExportc, wExportCpp,
|
declPragmas = {wImportc, wImportObjC, wImportCpp, wImportJs, wExportc, wExportCpp,
|
||||||
wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed}
|
wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed}
|
||||||
## common pragmas for declarations, to a good approximation
|
## common pragmas for declarations, to a good approximation
|
||||||
procPragmas* = declPragmas + {FirstCallConv..LastCallConv,
|
procPragmas* = declPragmas + {FirstCallConv..LastCallConv,
|
||||||
|
|
@ -803,6 +803,22 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
else: invalidPragma(c, it)
|
else: invalidPragma(c, it)
|
||||||
of wImportCpp:
|
of wImportCpp:
|
||||||
processImportCpp(c, sym, getOptionalStr(c, it, "$1"), it.info)
|
processImportCpp(c, sym, getOptionalStr(c, it, "$1"), it.info)
|
||||||
|
of wImportJs:
|
||||||
|
if c.config.cmd != cmdCompileToJS:
|
||||||
|
localError(c.config, it.info, "importjs pragma only supported when compiling to js.")
|
||||||
|
var strArg: PNode = nil
|
||||||
|
if it.kind in nkPragmaCallKinds:
|
||||||
|
strArg = it[1]
|
||||||
|
if strArg.kind notin {nkStrLit..nkTripleStrLit}:
|
||||||
|
localError(c.config, it.info, errStringLiteralExpected)
|
||||||
|
incl(sym.flags, sfImportc)
|
||||||
|
incl(sym.flags, sfInfixCall)
|
||||||
|
if strArg == nil:
|
||||||
|
if sym.kind in skProcKinds:
|
||||||
|
message(c.config, n.info, warnDeprecated, "procedure import should have an import pattern")
|
||||||
|
setExternName(c, sym, sym.name.s, it.info)
|
||||||
|
else:
|
||||||
|
setExternName(c, sym, strArg.strVal, it.info)
|
||||||
of wImportObjC:
|
of wImportObjC:
|
||||||
processImportObjC(c, sym, getOptionalStr(c, it, "$1"), it.info)
|
processImportObjC(c, sym, getOptionalStr(c, it, "$1"), it.info)
|
||||||
of wAlign:
|
of wAlign:
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ type
|
||||||
wImmediate, wConstructor, wDestructor, wDelegator, wOverride,
|
wImmediate, wConstructor, wDestructor, wDelegator, wOverride,
|
||||||
wImportCpp, wImportObjC,
|
wImportCpp, wImportObjC,
|
||||||
wImportCompilerProc,
|
wImportCompilerProc,
|
||||||
wImportc, wExportc, wExportCpp, wExportNims, wIncompleteStruct, wRequiresInit,
|
wImportc, wImportJs, wExportc, wExportCpp, wExportNims, wIncompleteStruct, wRequiresInit,
|
||||||
wAlign, wNodecl, wPure, wSideEffect, wHeader,
|
wAlign, wNodecl, wPure, wSideEffect, wHeader,
|
||||||
wNoSideEffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib,
|
wNoSideEffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib,
|
||||||
wCompilerProc, wCore, wProcVar, wBase, wUsed,
|
wCompilerProc, wCore, wProcVar, wBase, wUsed,
|
||||||
|
|
@ -129,7 +129,7 @@ const
|
||||||
|
|
||||||
"immediate", "constructor", "destructor", "delegator", "override",
|
"immediate", "constructor", "destructor", "delegator", "override",
|
||||||
"importcpp", "importobjc",
|
"importcpp", "importobjc",
|
||||||
"importcompilerproc", "importc", "exportc", "exportcpp", "exportnims",
|
"importcompilerproc", "importc", "importjs", "exportc", "exportcpp", "exportnims",
|
||||||
"incompletestruct",
|
"incompletestruct",
|
||||||
"requiresinit", "align", "nodecl", "pure", "sideeffect",
|
"requiresinit", "align", "nodecl", "pure", "sideeffect",
|
||||||
"header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib",
|
"header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib",
|
||||||
|
|
|
||||||
|
|
@ -6596,6 +6596,14 @@ this to work. The conditional symbol ``cpp`` is defined when the compiler
|
||||||
emits C++ code.
|
emits C++ code.
|
||||||
|
|
||||||
|
|
||||||
|
ImportJs pragma
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Similar to the `importcpp pragma for C++ <#foreign-function-interface-importc-pragma>`_,
|
||||||
|
the ``importjs`` pragma can be used to import Javascript methods or
|
||||||
|
symbols in general. The generated code then uses the Javascript method
|
||||||
|
calling syntax: ``obj.method(arg)``.
|
||||||
|
|
||||||
Namespaces
|
Namespaces
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
|
@ -6993,13 +7001,14 @@ spelled*:
|
||||||
.. code-block::
|
.. code-block::
|
||||||
proc printf(formatstr: cstring) {.header: "<stdio.h>", importc: "printf", varargs.}
|
proc printf(formatstr: cstring) {.header: "<stdio.h>", importc: "printf", varargs.}
|
||||||
|
|
||||||
Note that this pragma is somewhat of a misnomer: Other backends do provide
|
Note that this pragma has been abused in the past to also work in the
|
||||||
the same feature under the same name. Also, if one is interfacing with C++
|
js backand for js objects and functions. : Other backends do provide
|
||||||
the `ImportCpp pragma <manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and
|
the same feature under the same name. Also, when the target language
|
||||||
interfacing with Objective-C the `ImportObjC pragma
|
is not set to C, other pragmas are available:
|
||||||
<manual.html#implementation-specific-pragmas-importobjc-pragma>`_ can be used.
|
|
||||||
|
|
||||||
The string literal passed to ``importc`` can be a format string:
|
* `importcpp <manual.html#implementation-specific-pragmas-importcpp-pragma>`_
|
||||||
|
* `importobjc <manual.html#implementation-specific-pragmas-importobjc-pragma>`_
|
||||||
|
* `importjs <manul.html#implementation-specific-pragmas-importjs-pragma>`_
|
||||||
|
|
||||||
.. code-block:: Nim
|
.. code-block:: Nim
|
||||||
proc p(s: cstring) {.importc: "prefix$1".}
|
proc p(s: cstring) {.importc: "prefix$1".}
|
||||||
|
|
|
||||||
|
|
@ -292,8 +292,8 @@ macro `.()`*(obj: JsObject,
|
||||||
{.importcpp: `importString`, gensym, discardable.}
|
{.importcpp: `importString`, gensym, discardable.}
|
||||||
helper(`obj`)
|
helper(`obj`)
|
||||||
for idx in 0 ..< args.len:
|
for idx in 0 ..< args.len:
|
||||||
let paramName = newIdentNode(!("param" & $idx))
|
let paramName = newIdentNode("param" & $idx)
|
||||||
result[0][3].add newIdentDefs(paramName, newIdentNode(!"JsObject"))
|
result[0][3].add newIdentDefs(paramName, newIdentNode("JsObject"))
|
||||||
result[1].add args[idx].copyNimTree
|
result[1].add args[idx].copyNimTree
|
||||||
|
|
||||||
macro `.`*[K: cstring, V](obj: JsAssoc[K, V],
|
macro `.`*[K: cstring, V](obj: JsAssoc[K, V],
|
||||||
|
|
@ -425,7 +425,7 @@ macro `{}`*(typ: typedesc, xs: varargs[untyped]): auto =
|
||||||
## # This generates roughly the same JavaScript as:
|
## # This generates roughly the same JavaScript as:
|
||||||
## {.emit: "var obj = {a: 1, k: "foo", d: 42};".}
|
## {.emit: "var obj = {a: 1, k: "foo", d: 42};".}
|
||||||
##
|
##
|
||||||
let a = !"a"
|
let a = ident"a"
|
||||||
var body = quote do:
|
var body = quote do:
|
||||||
var `a` {.noinit.}: `typ`
|
var `a` {.noinit.}: `typ`
|
||||||
{.emit: "`a` = {};".}
|
{.emit: "`a` = {};".}
|
||||||
|
|
@ -488,7 +488,7 @@ macro bindMethod*(procedure: typed): auto =
|
||||||
error("Argument has to be a proc or a symbol corresponding to a proc.")
|
error("Argument has to be a proc or a symbol corresponding to a proc.")
|
||||||
var
|
var
|
||||||
rawProc = if procedure.kind == nnkSym:
|
rawProc = if procedure.kind == nnkSym:
|
||||||
getImpl(procedure.symbol)
|
getImpl(procedure)
|
||||||
else:
|
else:
|
||||||
procedure
|
procedure
|
||||||
args = rawProc[3]
|
args = rawProc[3]
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ true
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import macros, jsffi, jsconsole
|
import jsffi, jsconsole
|
||||||
|
|
||||||
# Tests for JsObject
|
# Tests for JsObject
|
||||||
# Test JsObject []= and []
|
# Test JsObject []= and []
|
||||||
|
|
@ -127,7 +127,7 @@ block:
|
||||||
block:
|
block:
|
||||||
proc test(): bool =
|
proc test(): bool =
|
||||||
{. emit: "var comparison = {a: 22, b: 'test'};" .}
|
{. emit: "var comparison = {a: 22, b: 'test'};" .}
|
||||||
var comparison {. importc, nodecl .}: JsObject
|
var comparison {. importjs, nodecl .}: JsObject
|
||||||
let obj = newJsObject()
|
let obj = newJsObject()
|
||||||
obj.a = 22
|
obj.a = 22
|
||||||
obj.b = "test".cstring
|
obj.b = "test".cstring
|
||||||
|
|
@ -138,7 +138,7 @@ block:
|
||||||
block:
|
block:
|
||||||
proc test(): bool =
|
proc test(): bool =
|
||||||
{. emit: "var comparison = {a: 22, b: 'test'};" .}
|
{. emit: "var comparison = {a: 22, b: 'test'};" .}
|
||||||
var comparison {. importc, nodecl .}: JsObject
|
var comparison {. importjs, nodecl .}: JsObject
|
||||||
let obj = JsObject{ a: 22, b: "test".cstring }
|
let obj = JsObject{ a: 22, b: "test".cstring }
|
||||||
obj.a == comparison.a and obj.b == comparison.b
|
obj.a == comparison.a and obj.b == comparison.b
|
||||||
echo test()
|
echo test()
|
||||||
|
|
@ -233,7 +233,7 @@ block:
|
||||||
block:
|
block:
|
||||||
proc test(): bool =
|
proc test(): bool =
|
||||||
{. emit: "var comparison = {a: 22, b: 55};" .}
|
{. emit: "var comparison = {a: 22, b: 55};" .}
|
||||||
var comparison {. importcpp, nodecl .}: JsAssoc[cstring, int]
|
var comparison {. importjs, nodecl .}: JsAssoc[cstring, int]
|
||||||
let obj = newJsAssoc[cstring, int]()
|
let obj = newJsAssoc[cstring, int]()
|
||||||
obj.a = 22
|
obj.a = 22
|
||||||
obj.b = 55
|
obj.b = 55
|
||||||
|
|
@ -244,7 +244,7 @@ block:
|
||||||
block:
|
block:
|
||||||
proc test(): bool =
|
proc test(): bool =
|
||||||
{. emit: "var comparison = {a: 22, b: 55};" .}
|
{. emit: "var comparison = {a: 22, b: 55};" .}
|
||||||
var comparison {. importcpp, nodecl .}: JsAssoc[cstring, int]
|
var comparison {. importjs, nodecl .}: JsAssoc[cstring, int]
|
||||||
let obj = JsAssoc[cstring, int]{ a: 22, b: 55 }
|
let obj = JsAssoc[cstring, int]{ a: 22, b: 55 }
|
||||||
var working = true
|
var working = true
|
||||||
working = working and
|
working = working and
|
||||||
|
|
@ -264,7 +264,7 @@ block:
|
||||||
b: cstring
|
b: cstring
|
||||||
proc test(): bool =
|
proc test(): bool =
|
||||||
{. emit: "var comparison = {a: 1};" .}
|
{. emit: "var comparison = {a: 1};" .}
|
||||||
var comparison {. importc, nodecl .}: TestObject
|
var comparison {. importjs, nodecl .}: TestObject
|
||||||
let obj = TestObject{ a: 1 }
|
let obj = TestObject{ a: 1 }
|
||||||
obj == comparison
|
obj == comparison
|
||||||
echo test()
|
echo test()
|
||||||
|
|
@ -283,7 +283,7 @@ block:
|
||||||
|
|
||||||
block:
|
block:
|
||||||
{.emit: "function jsProc(n) { return n; }" .}
|
{.emit: "function jsProc(n) { return n; }" .}
|
||||||
proc jsProc(x: int32): JsObject {.importc: "jsProc".}
|
proc jsProc(x: int32): JsObject {.importjs: "jsProc(#)".}
|
||||||
|
|
||||||
proc test() =
|
proc test() =
|
||||||
var x = jsProc(1)
|
var x = jsProc(1)
|
||||||
|
|
@ -296,8 +296,6 @@ block:
|
||||||
|
|
||||||
test()
|
test()
|
||||||
|
|
||||||
import macros
|
|
||||||
|
|
||||||
block:
|
block:
|
||||||
{.emit:
|
{.emit:
|
||||||
"""
|
"""
|
||||||
|
|
@ -310,8 +308,8 @@ block:
|
||||||
type Event = object
|
type Event = object
|
||||||
name: cstring
|
name: cstring
|
||||||
|
|
||||||
proc on(event: cstring, handler: proc) {.importc: "on".}
|
proc on(event: cstring, handler: proc) {.importjs: "on(#,#)".}
|
||||||
var jslib {.importc: "jslib", nodecl.}: JsObject
|
var jslib {.importjs: "jslib", nodecl.}: JsObject
|
||||||
|
|
||||||
on("click") do (e: Event):
|
on("click") do (e: Event):
|
||||||
console.log e
|
console.log e
|
||||||
|
|
|
||||||
338
tests/js/tjsffi_old.nim
Normal file
338
tests/js/tjsffi_old.nim
Normal file
|
|
@ -0,0 +1,338 @@
|
||||||
|
discard """
|
||||||
|
output: '''
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
3
|
||||||
|
2
|
||||||
|
12
|
||||||
|
Event { name: 'click: test' }
|
||||||
|
Event { name: 'reloaded: test' }
|
||||||
|
Event { name: 'updates: test' }
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
## same as tjsffi, but this test uses the old names: importc and
|
||||||
|
## importcpp. This test is for backwards compatibility.
|
||||||
|
|
||||||
|
import macros, jsffi, jsconsole
|
||||||
|
|
||||||
|
# Tests for JsObject
|
||||||
|
# Test JsObject []= and []
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
let obj = newJsObject()
|
||||||
|
var working = true
|
||||||
|
obj["a"] = 11
|
||||||
|
obj["b"] = "test"
|
||||||
|
obj["c"] = "test".cstring
|
||||||
|
working = working and obj["a"].to(int) == 11
|
||||||
|
working = working and obj["c"].to(cstring) == "test".cstring
|
||||||
|
working
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsObject .= and .
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
let obj = newJsObject()
|
||||||
|
var working = true
|
||||||
|
obj.a = 11
|
||||||
|
obj.b = "test"
|
||||||
|
obj.c = "test".cstring
|
||||||
|
obj.`$!&` = 42
|
||||||
|
obj.`while` = 99
|
||||||
|
working = working and obj.a.to(int) == 11
|
||||||
|
working = working and obj.b.to(string) == "test"
|
||||||
|
working = working and obj.c.to(cstring) == "test".cstring
|
||||||
|
working = working and obj.`$!&`.to(int) == 42
|
||||||
|
working = working and obj.`while`.to(int) == 99
|
||||||
|
working
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsObject .()
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
let obj = newJsObject()
|
||||||
|
obj.`?!$` = proc(x, y, z: int, t: cstring): cstring = t & $(x + y + z)
|
||||||
|
obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == cstring"Result is: 6"
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsObject []()
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
let obj = newJsObject()
|
||||||
|
obj.a = proc(x, y, z: int, t: string): string = t & $(x + y + z)
|
||||||
|
let call = obj["a"].to(proc(x, y, z: int, t: string): string)
|
||||||
|
call(1, 2, 3, "Result is: ") == "Result is: 6"
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsObject Iterators
|
||||||
|
block:
|
||||||
|
proc testPairs(): bool =
|
||||||
|
let obj = newJsObject()
|
||||||
|
var working = true
|
||||||
|
obj.a = 10
|
||||||
|
obj.b = 20
|
||||||
|
obj.c = 30
|
||||||
|
for k, v in obj.pairs:
|
||||||
|
case $k
|
||||||
|
of "a":
|
||||||
|
working = working and v.to(int) == 10
|
||||||
|
of "b":
|
||||||
|
working = working and v.to(int) == 20
|
||||||
|
of "c":
|
||||||
|
working = working and v.to(int) == 30
|
||||||
|
else:
|
||||||
|
return false
|
||||||
|
working
|
||||||
|
proc testItems(): bool =
|
||||||
|
let obj = newJsObject()
|
||||||
|
var working = true
|
||||||
|
obj.a = 10
|
||||||
|
obj.b = 20
|
||||||
|
obj.c = 30
|
||||||
|
for v in obj.items:
|
||||||
|
working = working and v.to(int) in [10, 20, 30]
|
||||||
|
working
|
||||||
|
proc testKeys(): bool =
|
||||||
|
let obj = newJsObject()
|
||||||
|
var working = true
|
||||||
|
obj.a = 10
|
||||||
|
obj.b = 20
|
||||||
|
obj.c = 30
|
||||||
|
for v in obj.keys:
|
||||||
|
working = working and $v in ["a", "b", "c"]
|
||||||
|
working
|
||||||
|
proc test(): bool = testPairs() and testItems() and testKeys()
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsObject equality
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
{. emit: "var comparison = {a: 22, b: 'test'};" .}
|
||||||
|
var comparison {. importc, nodecl .}: JsObject
|
||||||
|
let obj = newJsObject()
|
||||||
|
obj.a = 22
|
||||||
|
obj.b = "test".cstring
|
||||||
|
obj.a == comparison.a and obj.b == comparison.b
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsObject literal
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
{. emit: "var comparison = {a: 22, b: 'test'};" .}
|
||||||
|
var comparison {. importc, nodecl .}: JsObject
|
||||||
|
let obj = JsObject{ a: 22, b: "test".cstring }
|
||||||
|
obj.a == comparison.a and obj.b == comparison.b
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Tests for JsAssoc
|
||||||
|
# Test JsAssoc []= and []
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
let obj = newJsAssoc[int, int]()
|
||||||
|
var working = true
|
||||||
|
obj[1] = 11
|
||||||
|
working = working and not compiles(obj["a"] = 11)
|
||||||
|
working = working and not compiles(obj["a"])
|
||||||
|
working = working and not compiles(obj[2] = "test")
|
||||||
|
working = working and not compiles(obj[3] = "test".cstring)
|
||||||
|
working = working and obj[1] == 11
|
||||||
|
working
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsAssoc .= and .
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
let obj = newJsAssoc[cstring, int]()
|
||||||
|
var working = true
|
||||||
|
obj.a = 11
|
||||||
|
obj.`$!&` = 42
|
||||||
|
working = working and not compiles(obj.b = "test")
|
||||||
|
working = working and not compiles(obj.c = "test".cstring)
|
||||||
|
working = working and obj.a == 11
|
||||||
|
working = working and obj.`$!&` == 42
|
||||||
|
working
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsAssoc .()
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
let obj = newJsAssoc[cstring, proc(e: int): int]()
|
||||||
|
obj.a = proc(e: int): int = e * e
|
||||||
|
obj.a(10) == 100
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsAssoc []()
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
let obj = newJsAssoc[cstring, proc(e: int): int]()
|
||||||
|
obj.a = proc(e: int): int = e * e
|
||||||
|
let call = obj["a"]
|
||||||
|
call(10) == 100
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsAssoc Iterators
|
||||||
|
block:
|
||||||
|
proc testPairs(): bool =
|
||||||
|
let obj = newJsAssoc[cstring, int]()
|
||||||
|
var working = true
|
||||||
|
obj.a = 10
|
||||||
|
obj.b = 20
|
||||||
|
obj.c = 30
|
||||||
|
for k, v in obj.pairs:
|
||||||
|
case $k
|
||||||
|
of "a":
|
||||||
|
working = working and v == 10
|
||||||
|
of "b":
|
||||||
|
working = working and v == 20
|
||||||
|
of "c":
|
||||||
|
working = working and v == 30
|
||||||
|
else:
|
||||||
|
return false
|
||||||
|
working
|
||||||
|
proc testItems(): bool =
|
||||||
|
let obj = newJsAssoc[cstring, int]()
|
||||||
|
var working = true
|
||||||
|
obj.a = 10
|
||||||
|
obj.b = 20
|
||||||
|
obj.c = 30
|
||||||
|
for v in obj.items:
|
||||||
|
working = working and v in [10, 20, 30]
|
||||||
|
working
|
||||||
|
proc testKeys(): bool =
|
||||||
|
let obj = newJsAssoc[cstring, int]()
|
||||||
|
var working = true
|
||||||
|
obj.a = 10
|
||||||
|
obj.b = 20
|
||||||
|
obj.c = 30
|
||||||
|
for v in obj.keys:
|
||||||
|
working = working and v in [cstring"a", cstring"b", cstring"c"]
|
||||||
|
working
|
||||||
|
proc test(): bool = testPairs() and testItems() and testKeys()
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsAssoc equality
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
{. emit: "var comparison = {a: 22, b: 55};" .}
|
||||||
|
var comparison {. importcpp, nodecl .}: JsAssoc[cstring, int]
|
||||||
|
let obj = newJsAssoc[cstring, int]()
|
||||||
|
obj.a = 22
|
||||||
|
obj.b = 55
|
||||||
|
obj.a == comparison.a and obj.b == comparison.b
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test JsAssoc literal
|
||||||
|
block:
|
||||||
|
proc test(): bool =
|
||||||
|
{. emit: "var comparison = {a: 22, b: 55};" .}
|
||||||
|
var comparison {. importcpp, nodecl .}: JsAssoc[cstring, int]
|
||||||
|
let obj = JsAssoc[cstring, int]{ a: 22, b: 55 }
|
||||||
|
var working = true
|
||||||
|
working = working and
|
||||||
|
compiles(JsAssoc[int, int]{ 1: 22, 2: 55 })
|
||||||
|
working = working and
|
||||||
|
comparison.a == obj.a and comparison.b == obj.b
|
||||||
|
working = working and
|
||||||
|
not compiles(JsAssoc[cstring, int]{ a: "test" })
|
||||||
|
working
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Tests for macros on non-JsRoot objects
|
||||||
|
# Test lit
|
||||||
|
block:
|
||||||
|
type TestObject = object
|
||||||
|
a: int
|
||||||
|
b: cstring
|
||||||
|
proc test(): bool =
|
||||||
|
{. emit: "var comparison = {a: 1};" .}
|
||||||
|
var comparison {. importc, nodecl .}: TestObject
|
||||||
|
let obj = TestObject{ a: 1 }
|
||||||
|
obj == comparison
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
# Test bindMethod
|
||||||
|
block:
|
||||||
|
type TestObject = object
|
||||||
|
a: int
|
||||||
|
onWhatever: proc(e: int): int
|
||||||
|
proc handleWhatever(this: TestObject, e: int): int =
|
||||||
|
e + this.a
|
||||||
|
proc test(): bool =
|
||||||
|
let obj = TestObject(a: 9, onWhatever: bindMethod(handleWhatever))
|
||||||
|
obj.onWhatever(1) == 10
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
block:
|
||||||
|
{.emit: "function jsProc(n) { return n; }" .}
|
||||||
|
proc jsProc(x: int32): JsObject {.importc: "jsProc".}
|
||||||
|
|
||||||
|
proc test() =
|
||||||
|
var x = jsProc(1)
|
||||||
|
var y = jsProc(2)
|
||||||
|
console.log x + y
|
||||||
|
console.log ++x
|
||||||
|
|
||||||
|
x += jsProc(10)
|
||||||
|
console.log x
|
||||||
|
|
||||||
|
test()
|
||||||
|
|
||||||
|
import macros
|
||||||
|
|
||||||
|
block:
|
||||||
|
{.emit:
|
||||||
|
"""
|
||||||
|
function Event(name) { this.name = name; }
|
||||||
|
function on(eventName, eventHandler) { eventHandler(new Event(eventName + ": test")); }
|
||||||
|
var jslib = { "on": on, "subscribe": on };
|
||||||
|
"""
|
||||||
|
.}
|
||||||
|
|
||||||
|
type Event = object
|
||||||
|
name: cstring
|
||||||
|
|
||||||
|
proc on(event: cstring, handler: proc) {.importc: "on".}
|
||||||
|
var jslib {.importc: "jslib", nodecl.}: JsObject
|
||||||
|
|
||||||
|
on("click") do (e: Event):
|
||||||
|
console.log e
|
||||||
|
|
||||||
|
jslib.on("reloaded") do:
|
||||||
|
console.log jsarguments[0]
|
||||||
|
|
||||||
|
# this test case is different from the above, because
|
||||||
|
# `subscribe` is not overloaded in the current scope
|
||||||
|
jslib.subscribe("updates"):
|
||||||
|
console.log jsarguments[0]
|
||||||
|
|
||||||
|
block:
|
||||||
|
|
||||||
|
echo jsUndefined == jsNull
|
||||||
|
echo jsUndefined == nil
|
||||||
|
echo jsNull == nil
|
||||||
|
echo jsUndefined.isNil
|
||||||
|
echo jsNull.isNil
|
||||||
|
echo jsNull.isNull
|
||||||
|
echo jsUndefined.isUndefined
|
||||||
Loading…
Add table
Add a link
Reference in a new issue