Skip to content

Commit

Permalink
small improvements and fix for symbol handling
Browse files Browse the repository at this point in the history
  • Loading branch information
rbri committed Apr 20, 2022
1 parent ff86f62 commit 08e8860
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 6 deletions.
25 changes: 19 additions & 6 deletions src/org/mozilla/javascript/NativeJSON.java
Original file line number Diff line number Diff line change
Expand Up @@ -288,14 +288,16 @@ private static Object str(Object key, Scriptable holder, StringifyState state) {
Object value = null;
Object unwrappedJavaValue = null;

String keyString = null;
int keyInt = 0;
if (key instanceof String) {
value = getProperty(holder, (String) key);
keyString = (String) key;
value = getProperty(holder, keyString);
} else {
value = getProperty(holder, ((Number) key).intValue());
keyInt = ((Number) key).intValue();
value = getProperty(holder, keyInt);
}

if (ScriptRuntime.isSymbol(value)) return Undefined.instance;

if (value instanceof Scriptable && hasProperty((Scriptable) value, "toJSON")) {
Object toJSON = getProperty((Scriptable) value, "toJSON");
if (toJSON instanceof Callable) {
Expand All @@ -304,14 +306,23 @@ private static Object str(Object key, Scriptable holder, StringifyState state) {
state.cx,
(Scriptable) value,
"toJSON",
new Object[] {ScriptRuntime.toString(key)});
new Object[] {
keyString == null ? Integer.toString(keyInt) : keyString
});
}
} else if (value instanceof BigInteger) {
Scriptable bigInt = ScriptRuntime.toObject(state.cx, state.scope, value);
if (hasProperty(bigInt, "toJSON")) {
Object toJSON = getProperty(bigInt, "toJSON");
if (toJSON instanceof Callable) {
value = callMethod(state.cx, bigInt, "toJSON", new Object[] {key});
value =
callMethod(
state.cx,
bigInt,
"toJSON",
new Object[] {
keyString == null ? Integer.toString(keyInt) : keyString
});
}
}
}
Expand All @@ -320,6 +331,8 @@ private static Object str(Object key, Scriptable holder, StringifyState state) {
value = state.replacer.call(state.cx, state.scope, holder, new Object[] {key, value});
}

if (ScriptRuntime.isSymbol(value)) return Undefined.instance;

if (value instanceof NativeNumber) {
value = Double.valueOf(ScriptRuntime.toNumber(value));
} else if (value instanceof NativeString) {
Expand Down
32 changes: 32 additions & 0 deletions testsrc/jstests/es6/stringify-symbol-value.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
load('testsrc/assert.js');

// check for symbol after the replacer was called

var count = 0;
var sym = Symbol('testSymbol');

function replacerSym(key, value) {
count++;
if ('test' == key) return sym;
return value;
}

function replacerStr(key, value) {
count++;
if ('test' == key) return 'newStr';
return value;
}

var obj = {test: 'value'};
var actual = JSON.stringify(obj, replacerSym);
assertEquals("{}", actual);
assertEquals(2, count);

count = 0;
var obj = {test: sym};
var actual = JSON.stringify(obj, replacerStr);
assertEquals('{"test":"newStr"}', actual);
assertEquals(2, count);


"success"
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.mozilla.javascript.tests.es6;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.drivers.LanguageVersion;
import org.mozilla.javascript.drivers.RhinoTest;
import org.mozilla.javascript.drivers.ScriptTestsBase;

@RhinoTest("testsrc/jstests/es6/stringify-symbol-value.js")
@LanguageVersion(Context.VERSION_ES6)
public class StringifySymbolValueTest extends ScriptTestsBase {}

0 comments on commit 08e8860

Please sign in to comment.