311 public void remove() { |
311 public void remove() { |
312 throw new UnsupportedOperationException("remove"); |
312 throw new UnsupportedOperationException("remove"); |
313 } |
313 } |
314 } |
314 } |
315 |
315 |
316 /** |
316 // value Iterator for important Java objects - arrays, maps, iterables. |
317 * Returns an iterator over property values used in the {@code for each...in} statement. Aside from built-in JS |
317 private static Iterator<?> iteratorForJavaArrayOrList(final Object obj) { |
318 * objects, it also operates on Java arrays, any {@link Iterable}, as well as on {@link Map} objects, iterating over |
|
319 * map values. |
|
320 * @param obj object to iterate on. |
|
321 * @return iterator over the object's property values. |
|
322 */ |
|
323 public static Iterator<?> toValueIterator(final Object obj) { |
|
324 if (obj instanceof ScriptObject) { |
|
325 return ((ScriptObject)obj).valueIterator(); |
|
326 } |
|
327 |
|
328 if (obj != null && obj.getClass().isArray()) { |
318 if (obj != null && obj.getClass().isArray()) { |
329 final Object array = obj; |
319 final Object array = obj; |
330 final int length = Array.getLength(obj); |
320 final int length = Array.getLength(obj); |
331 |
321 |
332 return new Iterator<Object>() { |
322 return new Iterator<Object>() { |
350 throw new UnsupportedOperationException("remove"); |
340 throw new UnsupportedOperationException("remove"); |
351 } |
341 } |
352 }; |
342 }; |
353 } |
343 } |
354 |
344 |
|
345 if (obj instanceof Iterable) { |
|
346 return ((Iterable<?>)obj).iterator(); |
|
347 } |
|
348 |
|
349 return null; |
|
350 } |
|
351 |
|
352 /** |
|
353 * Returns an iterator over property values used in the {@code for each...in} statement. Aside from built-in JS |
|
354 * objects, it also operates on Java arrays, any {@link Iterable}, as well as on {@link Map} objects, iterating over |
|
355 * map values. |
|
356 * @param obj object to iterate on. |
|
357 * @return iterator over the object's property values. |
|
358 */ |
|
359 public static Iterator<?> toValueIterator(final Object obj) { |
|
360 if (obj instanceof ScriptObject) { |
|
361 return ((ScriptObject)obj).valueIterator(); |
|
362 } |
|
363 |
355 if (obj instanceof JSObject) { |
364 if (obj instanceof JSObject) { |
356 return ((JSObject)obj).values().iterator(); |
365 return ((JSObject)obj).values().iterator(); |
357 } |
366 } |
358 |
367 |
|
368 final Iterator<?> itr = iteratorForJavaArrayOrList(obj); |
|
369 if (itr != null) { |
|
370 return itr; |
|
371 } |
|
372 |
359 if (obj instanceof Map) { |
373 if (obj instanceof Map) { |
360 return ((Map<?,?>)obj).values().iterator(); |
374 return ((Map<?,?>)obj).values().iterator(); |
361 } |
|
362 |
|
363 if (obj instanceof Iterable) { |
|
364 return ((Iterable<?>)obj).iterator(); |
|
365 } |
375 } |
366 |
376 |
367 final Object wrapped = Global.instance().wrapAsObject(obj); |
377 final Object wrapped = Global.instance().wrapAsObject(obj); |
368 if (wrapped instanceof ScriptObject) { |
378 if (wrapped instanceof ScriptObject) { |
369 return ((ScriptObject)wrapped).valueIterator(); |
379 return ((ScriptObject)wrapped).valueIterator(); |
378 * |
388 * |
379 * @param obj object to iterate on. |
389 * @param obj object to iterate on. |
380 * @return iterator based on the ECMA 6 Iterator interface. |
390 * @return iterator based on the ECMA 6 Iterator interface. |
381 */ |
391 */ |
382 public static Iterator<?> toES6Iterator(final Object obj) { |
392 public static Iterator<?> toES6Iterator(final Object obj) { |
|
393 // if not a ScriptObject, try convenience iterator for Java objects! |
|
394 if (!(obj instanceof ScriptObject)) { |
|
395 final Iterator<?> itr = iteratorForJavaArrayOrList(obj); |
|
396 if (itr != null) { |
|
397 return itr; |
|
398 } |
|
399 } |
|
400 |
383 final Global global = Global.instance(); |
401 final Global global = Global.instance(); |
384 final Object iterator = AbstractIterator.getIterator(Global.toObject(obj), global); |
402 final Object iterator = AbstractIterator.getIterator(Global.toObject(obj), global); |
385 |
403 |
386 final InvokeByName nextInvoker = AbstractIterator.getNextInvoker(global); |
404 final InvokeByName nextInvoker = AbstractIterator.getNextInvoker(global); |
387 final MethodHandle doneInvoker = AbstractIterator.getDoneInvoker(global); |
405 final MethodHandle doneInvoker = AbstractIterator.getDoneInvoker(global); |