src/jdk/nashorn/internal/runtime/JSONFunctions.java

Print this page




  84         Node node;
  85 
  86         try {
  87             node = parser.parse();
  88         } catch (final ParserException e) {
  89             throw ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
  90         }
  91 
  92         final Global global = Context.getGlobal();
  93         Object unfiltered = convertNode(global, node);
  94         return applyReviver(global, unfiltered, reviver);
  95     }
  96 
  97     // -- Internals only below this point
  98 
  99     // parse helpers
 100 
 101     // apply 'reviver' function if available
 102     private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
 103         if (reviver instanceof ScriptFunction) {
 104             assert global instanceof Global;
 105             final ScriptObject root = global.newObject();
 106             root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
 107             return walk(root, "", (ScriptFunction)reviver);
 108         }
 109         return unfiltered;
 110     }
 111 
 112     // This is the abstract "Walk" operation from the spec.
 113     private static Object walk(final ScriptObject holder, final Object name, final ScriptFunction reviver) {
 114         final Object val = holder.get(name);
 115         if (val instanceof ScriptObject) {
 116             final ScriptObject     valueObj = (ScriptObject)val;
 117             final Iterator<String> iter     = valueObj.propertyIterator();
 118 
 119             while (iter.hasNext()) {
 120                 final String key        = iter.next();
 121                 final Object newElement = walk(valueObj, key, reviver);
 122 
 123                 if (newElement == ScriptRuntime.UNDEFINED) {
 124                     valueObj.delete(key, false);


 183                 final String name = pNode.getKeyName();
 184                 final Object value = convertNode(global, valueNode);
 185                 setPropertyValue(object, name, value, false);
 186             }
 187 
 188             return object;
 189         } else if (node instanceof UnaryNode) {
 190             // UnaryNode used only to represent negative number JSON value
 191             final UnaryNode unaryNode = (UnaryNode)node;
 192             return -((LiteralNode<?>)unaryNode.rhs()).getNumber();
 193         } else {
 194             return null;
 195         }
 196     }
 197 
 198     // add a new property if does not exist already, or else set old property
 199     private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) {
 200         final int index = ArrayIndex.getArrayIndex(name);
 201         if (ArrayIndex.isValidArrayIndex(index)) {
 202             // array index key
 203             sobj.defineOwnProperty(index, value);
 204         } else if (sobj.getMap().findProperty(name) != null) {
 205             // pre-existing non-inherited property, call set
 206             sobj.set(name, value, strict);
 207         } else {
 208             // add new property
 209             sobj.addOwnProperty(name, Property.WRITABLE_ENUMERABLE_CONFIGURABLE, value);
 210         }
 211     }
 212 
 213     // does the given IR node represent a numeric array?
 214     private static boolean isNumericArray(final Node[] values) {
 215         for (final Node node : values) {
 216             if (node instanceof LiteralNode && ((LiteralNode<?>)node).getValue() instanceof Number) {
 217                 continue;
 218             }
 219             return false;
 220         }
 221         return true;
 222     }
 223 }


  84         Node node;
  85 
  86         try {
  87             node = parser.parse();
  88         } catch (final ParserException e) {
  89             throw ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
  90         }
  91 
  92         final Global global = Context.getGlobal();
  93         Object unfiltered = convertNode(global, node);
  94         return applyReviver(global, unfiltered, reviver);
  95     }
  96 
  97     // -- Internals only below this point
  98 
  99     // parse helpers
 100 
 101     // apply 'reviver' function if available
 102     private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
 103         if (reviver instanceof ScriptFunction) {

 104             final ScriptObject root = global.newObject();
 105             root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
 106             return walk(root, "", (ScriptFunction)reviver);
 107         }
 108         return unfiltered;
 109     }
 110 
 111     // This is the abstract "Walk" operation from the spec.
 112     private static Object walk(final ScriptObject holder, final Object name, final ScriptFunction reviver) {
 113         final Object val = holder.get(name);
 114         if (val instanceof ScriptObject) {
 115             final ScriptObject     valueObj = (ScriptObject)val;
 116             final Iterator<String> iter     = valueObj.propertyIterator();
 117 
 118             while (iter.hasNext()) {
 119                 final String key        = iter.next();
 120                 final Object newElement = walk(valueObj, key, reviver);
 121 
 122                 if (newElement == ScriptRuntime.UNDEFINED) {
 123                     valueObj.delete(key, false);


 182                 final String name = pNode.getKeyName();
 183                 final Object value = convertNode(global, valueNode);
 184                 setPropertyValue(object, name, value, false);
 185             }
 186 
 187             return object;
 188         } else if (node instanceof UnaryNode) {
 189             // UnaryNode used only to represent negative number JSON value
 190             final UnaryNode unaryNode = (UnaryNode)node;
 191             return -((LiteralNode<?>)unaryNode.rhs()).getNumber();
 192         } else {
 193             return null;
 194         }
 195     }
 196 
 197     // add a new property if does not exist already, or else set old property
 198     private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) {
 199         final int index = ArrayIndex.getArrayIndex(name);
 200         if (ArrayIndex.isValidArrayIndex(index)) {
 201             // array index key
 202             sobj.defineOwnPropertyNoGap(index, value);
 203         } else if (sobj.getMap().findProperty(name) != null) {
 204             // pre-existing non-inherited property, call set
 205             sobj.set(name, value, strict);
 206         } else {
 207             // add new property
 208             sobj.addOwnProperty(name, Property.WRITABLE_ENUMERABLE_CONFIGURABLE, value);
 209         }
 210     }
 211 
 212     // does the given IR node represent a numeric array?
 213     private static boolean isNumericArray(final Node[] values) {
 214         for (final Node node : values) {
 215             if (node instanceof LiteralNode && ((LiteralNode<?>)node).getValue() instanceof Number) {
 216                 continue;
 217             }
 218             return false;
 219         }
 220         return true;
 221     }
 222 }