diff options
author | Michael Jendrusch <Jendrusch@stud.uni-heidelberg.de> | 2017-01-17 16:43:06 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-01-17 16:43:06 +0100 |
commit | 454547da8efe7e07b0c13254c6a000e805e2475e (patch) | |
tree | 08f4349d2c51670dd3b8b7d6d30cc4b4c244ad18 | |
parent | 54a6c5b34844322f2bb50222cb779dde02c6cad4 (diff) | |
download | Nim-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.nim | 15 | ||||
-rw-r--r-- | tests/js/tmangle.nim | 83 |
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() |