(Scriptable value, StringifyState state)
| 370 | } |
| 371 | |
| 372 | private static String jo(Scriptable value, StringifyState state) { |
| 373 | Object trackValue = value, unwrapped = null; |
| 374 | if (value instanceof Wrapper) { |
| 375 | trackValue = unwrapped = ((Wrapper) value).unwrap(); |
| 376 | } |
| 377 | |
| 378 | if (state.stack.contains(trackValue)) { |
| 379 | throw ScriptRuntime.typeErrorById("msg.cyclic.value", trackValue.getClass().getName()); |
| 380 | } |
| 381 | state.stack.push(trackValue); |
| 382 | |
| 383 | if (unwrapped instanceof Map) { |
| 384 | Map<?, ?> map = (Map<?, ?>) unwrapped; |
| 385 | Scriptable nObj = state.cx.newObject(state.scope); |
| 386 | for (Map.Entry<?, ?> entry : map.entrySet()) { |
| 387 | if (entry.getKey() instanceof Symbol) continue; |
| 388 | Object wrappedValue = Context.javaToJS(entry.getValue(), state.scope, state.cx); |
| 389 | int attributes; |
| 390 | String key; |
| 391 | if (entry.getKey() instanceof String) { |
| 392 | // Keys that are actually Strings are permanent and will not be |
| 393 | // overridden by other objects having the same toString value. |
| 394 | key = (String) entry.getKey(); |
| 395 | attributes = ScriptableObject.READONLY | ScriptableObject.PERMANENT; |
| 396 | } else { |
| 397 | // To avoid duplicate keys in JSON, replace previous key having the same |
| 398 | // toString value as the current object. |
| 399 | key = entry.getKey().toString(); |
| 400 | attributes = ScriptableObject.EMPTY; |
| 401 | } |
| 402 | try { |
| 403 | ScriptableObject.defineProperty(nObj, key, wrappedValue, attributes); |
| 404 | } catch (EcmaError error) { |
| 405 | // ignore TypeErrors if we tried to rewrite the property for a |
| 406 | // String key. |
| 407 | } |
| 408 | } |
| 409 | value = nObj; |
| 410 | } |
| 411 | |
| 412 | String stepback = state.indent; |
| 413 | state.indent = state.indent + state.gap; |
| 414 | Object[] k = null; |
| 415 | if (state.propertyList != null) { |
| 416 | k = state.propertyList; |
| 417 | } else { |
| 418 | k = value.getIds(); |
| 419 | } |
| 420 | |
| 421 | ArrayList<Object> partial = new ArrayList<>(); |
| 422 | |
| 423 | for (Object p : k) { |
| 424 | Object strP = str(p, value, state); |
| 425 | if (strP != Undefined.instance) { |
| 426 | String member = quote(p.toString()) + ":"; |
| 427 | if (state.gap.length() > 0) { |
| 428 | member = member + " "; |
| 429 | } |
no test coverage detected