make jsffi properly gensym (#22539)

fixes #21208
This commit is contained in:
metagn
2023-08-23 20:25:26 +03:00
committed by GitHub
parent 4f891aa50c
commit 03f267c801
2 changed files with 35 additions and 22 deletions

View File

@@ -227,36 +227,40 @@ macro `.`*(obj: JsObject, field: untyped): JsObject =
assert obj.a.to(int) == 20
if validJsName($field):
let importString = "#." & $field
let helperName = genSym(nskProc, "helper")
result = quote do:
proc helper(o: JsObject): JsObject
{.importjs: `importString`, gensym.}
helper(`obj`)
proc `helperName`(o: JsObject): JsObject
{.importjs: `importString`.}
`helperName`(`obj`)
else:
if not mangledNames.hasKey($field):
mangledNames[$field] = mangleJsName($field)
let importString = "#." & mangledNames[$field]
let helperName = genSym(nskProc, "helper")
result = quote do:
proc helper(o: JsObject): JsObject
{.importjs: `importString`, gensym.}
helper(`obj`)
proc `helperName`(o: JsObject): JsObject
{.importjs: `importString`.}
`helperName`(`obj`)
macro `.=`*(obj: JsObject, field, value: untyped): untyped =
## Experimental dot accessor (set) for type JsObject.
## Sets the value of a property of name `field` in a JsObject `x` to `value`.
if validJsName($field):
let importString = "#." & $field & " = #"
let helperName = genSym(nskProc, "helper")
result = quote do:
proc helper(o: JsObject, v: auto)
{.importjs: `importString`, gensym.}
helper(`obj`, `value`)
proc `helperName`(o: JsObject, v: auto)
{.importjs: `importString`.}
`helperName`(`obj`, `value`)
else:
if not mangledNames.hasKey($field):
mangledNames[$field] = mangleJsName($field)
let importString = "#." & mangledNames[$field] & " = #"
let helperName = genSym(nskProc, "helper")
result = quote do:
proc helper(o: JsObject, v: auto)
{.importjs: `importString`, gensym.}
helper(`obj`, `value`)
proc `helperName`(o: JsObject, v: auto)
{.importjs: `importString`.}
`helperName`(`obj`, `value`)
macro `.()`*(obj: JsObject,
field: untyped,
@@ -283,10 +287,11 @@ macro `.()`*(obj: JsObject,
if not mangledNames.hasKey($field):
mangledNames[$field] = mangleJsName($field)
importString = "#." & mangledNames[$field] & "(@)"
result = quote:
proc helper(o: JsObject): JsObject
{.importjs: `importString`, gensym, discardable.}
helper(`obj`)
let helperName = genSym(nskProc, "helper")
result = quote do:
proc `helperName`(o: JsObject): JsObject
{.importjs: `importString`, discardable.}
`helperName`(`obj`)
for idx in 0 ..< args.len:
let paramName = newIdentNode("param" & $idx)
result[0][3].add newIdentDefs(paramName, newIdentNode("JsObject"))
@@ -303,10 +308,11 @@ macro `.`*[K: cstring, V](obj: JsAssoc[K, V],
if not mangledNames.hasKey($field):
mangledNames[$field] = mangleJsName($field)
importString = "#." & mangledNames[$field]
let helperName = genSym(nskProc, "helper")
result = quote do:
proc helper(o: type(`obj`)): `obj`.V
{.importjs: `importString`, gensym.}
helper(`obj`)
proc `helperName`(o: type(`obj`)): `obj`.V
{.importjs: `importString`.}
`helperName`(`obj`)
macro `.=`*[K: cstring, V](obj: JsAssoc[K, V],
field: untyped,
@@ -320,10 +326,11 @@ macro `.=`*[K: cstring, V](obj: JsAssoc[K, V],
if not mangledNames.hasKey($field):
mangledNames[$field] = mangleJsName($field)
importString = "#." & mangledNames[$field] & " = #"
let helperName = genSym(nskProc, "helper")
result = quote do:
proc helper(o: type(`obj`), v: `obj`.V)
{.importjs: `importString`, gensym.}
helper(`obj`, `value`)
proc `helperName`(o: type(`obj`), v: `obj`.V)
{.importjs: `importString`.}
`helperName`(`obj`, `value`)
macro `.()`*[K: cstring, V: proc](obj: JsAssoc[K, V],
field: untyped,

View File

@@ -265,3 +265,9 @@ block: # test **
doAssert to(`**`(a + a, b), int) == 2
doAssert to(`**`(toJs(1) + toJs(1), toJs(2)), int) == 4
block: # issue #21208
type MyEnum = enum baz
var obj: JsObject
{.emit: "`obj` = {bar: {baz: 123}}".}
discard obj.bar.baz