summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorMichael Jendrusch <Jendrusch@stud.uni-heidelberg.de>2017-01-17 16:43:06 +0100
committerAndreas Rumpf <rumpf_a@web.de>2017-01-17 16:43:06 +0100
commit454547da8efe7e07b0c13254c6a000e805e2475e (patch)
tree08f4349d2c51670dd3b8b7d6d30cc4b4c244ad18
parent54a6c5b34844322f2bb50222cb779dde02c6cad4 (diff)
downloadNim-454547da8efe7e07b0c13254c6a000e805e2475e.tar.gz
Removed mangling of object fields for the js target only. (#5226)
* removed mangling of object fields for the js target only.

* changed default mangling behaviour for the php target as well.

* Added test for unorthodox field names (reserved words and operators). Adjusted field accessors and object constructors / new to be ECMAScript first edition compatible, when using fieldnames which are reserved words.
-rw-r--r--compiler/jsgen.nim15
-rw-r--r--tests/js/tmangle.nim83
2 files changed, 90 insertions, 8 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 50a74464a..70398a241 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -918,7 +918,7 @@ proc genFieldAddr(p: PProc, n: PNode, r: var TCompRes) =
   else:
     if b.sons[1].kind != nkSym: internalError(b.sons[1].info, "genFieldAddr")
     var f = b.sons[1].sym
-    if f.loc.r == nil: f.loc.r = mangleName(f, p.target)
+    if f.loc.r == nil: f.loc.r = rope(f.name.s)
     r.res = makeJSString($f.loc.r)
   internalAssert a.typ != etyBaseIndex
   r.address = a.res
@@ -934,9 +934,9 @@ proc genFieldAccess(p: PProc, n: PNode, r: var TCompRes) =
   else:
     if n.sons[1].kind != nkSym: internalError(n.sons[1].info, "genFieldAccess")
     var f = n.sons[1].sym
-    if f.loc.r == nil: f.loc.r = mangleName(f, p.target)
+    if f.loc.r == nil: f.loc.r = rope(f.name.s)
     if p.target == targetJS:
-      r.res = "$1.$2" % [r.res, f.loc.r]
+      r.res = "$1['$2']" % [r.res, f.loc.r]
     else:
       if {sfImportc, sfExportc} * f.flags != {}:
         r.res = "$1->$2" % [r.res, f.loc.r]
@@ -1351,10 +1351,9 @@ proc createRecordVarAux(p: PProc, rec: PNode, excludedFieldIDs: IntSet, output:
     if rec.sym.id notin excludedFieldIDs:
       if output.len > 0: output.add(", ")
       if p.target == targetJS:
-        output.add(mangleName(rec.sym, p.target))
-        output.add(": ")
+        output.addf("'$#': ", [rope(rec.sym.name.s)])
       else:
-        output.addf("'$#' => ", [mangleName(rec.sym, p.target)])
+        output.addf("'$#' => ", [rope(rec.sym.name.s)])
       output.add(createVar(p, rec.sym.typ, false))
   else: internalError(rec.info, "createRecordVarAux")
 
@@ -1859,9 +1858,9 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) =
     internalAssert it.kind == nkExprColonExpr
     gen(p, it.sons[1], a)
     var f = it.sons[0].sym
-    if f.loc.r == nil: f.loc.r = mangleName(f, p.target)
+    if f.loc.r == nil: f.loc.r = rope(f.name.s)
     fieldIDs.incl(f.id)
-    addf(initList, "$#: $#" | "'$#' => $#" , [f.loc.r, a.res])
+    addf(initList, "'$#': $#" | "'$#' => $#" , [f.loc.r, a.res])
   let t = skipTypes(n.typ, abstractInst + skipPtrs)
   createObjInitList(p, t, fieldIDs, initList)
   r.res = ("{$1}" | "array($#)") % [initList]
diff --git a/tests/js/tmangle.nim b/tests/js/tmangle.nim
new file mode 100644
index 000000000..91193d5a7
--- /dev/null
+++ b/tests/js/tmangle.nim
@@ -0,0 +1,83 @@
+discard """
+  output: '''true
+true
+true
+true
+true'''
+"""
+
+# Test not mangled:
+block:
+  type T = object
+    a: int
+    b: cstring
+  proc test(): bool =
+    let obj = T(a: 11, b: "foo")
+    {. emit: [result, " = (", obj, ".a == 11);"] .}
+    {. emit: [result, " = ", result, " && (", obj, ".b == \"foo\");"] .}
+  echo test()
+
+# Test indirect (fields in genAddr):
+block:
+  type T = object
+    a: int
+    b: cstring
+  var global = T(a: 11, b: "foo")
+  proc test(): bool =
+    var obj = T(a: 11, b: "foo")
+    {. emit: [result, " = (", obj.addr[], "[0].a == 11);"] .}
+    {. emit: [result, " = ", result, " && (", obj.addr[], "[0].b == \"foo\");"] .}
+    {. emit: [result, " = ", result, " && (", global, "[0].a == 11);"] .}
+    {. emit: [result, " = ", result, " && (", global, "[0].b == \"foo\");"] .}
+  echo test()
+
+# Test addr of field:
+block:
+  type T = object
+    a: int
+    b: cstring
+  proc test(): bool =
+    var obj = T(a: 11, b: "foo")
+    result = obj.a.addr[] == 11
+    result = result and obj.b.addr[] == "foo".cstring
+  echo test()
+
+# Test reserved words:
+block:
+  type T = ref object
+    `if`: int
+    `for`: int
+    `==`: cstring
+    `&&`: cstring
+  proc test(): bool =
+    var
+      obj1 = T(`if`: 11, `for`: 22, `==`: "foo", `&&`: "bar")
+      obj2: T
+    new obj2 # Test behaviour for createRecordVarAux.
+    result = obj1.`if` == 11
+    result = result and obj1.addr[].`for` == 22
+    result = result and obj1.`==` == "foo".cstring
+    result = result and obj1.`&&`.addr[] == "bar".cstring
+    result = result and obj2.`if` == 0
+    result = result and obj2.`for` == 0
+    result = result and obj2.`==`.isNil()
+    result = result and obj2.`&&`.isNil()
+  echo test()
+
+# Test importc / exportc fields:
+block:
+  type T = object
+    a: int
+    b {. importc: "notB" .}: cstring
+  type U = object
+    a: int
+    b {. exportc: "notB" .}: cstring
+  proc test(): bool =
+    var
+      obj1 = T(a: 11, b: "foo")
+      obj2 = U(a: 11, b: "foo")
+    {. emit: [result, " = (", obj1, ".a == 11);"] .}
+    {. emit: [result, " = ", result, " && (", obj1, ".notB == \"foo\");"] .}
+    {. emit: [result, " = (", obj2, ".a == 11);"] .}
+    {. emit: [result, " = ", result, " && (", obj2, ".notB == \"foo\");"] .}
+  echo test()