From dd255f9da01d14756c5271285a47d7021cbd517b Mon Sep 17 00:00:00 2001 From: Colorize Date: Mon, 9 Dec 2019 09:29:16 +0100 Subject: [PATCH] Extend the class library with the part of Spliterators that is used by Google Guava (#443) Add class library support for the part of Spliterators that is used by Google Guava. --- .../classlib/java/util/TSpliterators.java | 120 ++++++++++++++++++ .../classlib/java/util/SpliteratorsTest.java | 98 ++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 classlib/src/main/java/org/teavm/classlib/java/util/TSpliterators.java create mode 100644 classlib/src/test/java/org/teavm/classlib/java/util/SpliteratorsTest.java diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/TSpliterators.java b/classlib/src/main/java/org/teavm/classlib/java/util/TSpliterators.java new file mode 100644 index 000000000..0b16d2dd3 --- /dev/null +++ b/classlib/src/main/java/org/teavm/classlib/java/util/TSpliterators.java @@ -0,0 +1,120 @@ +/* + * Copyright 2017 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.classlib.java.util; + +import java.util.Collection; +import java.util.Iterator; +import java.util.function.Consumer; +import java.util.function.IntConsumer; + +public class TSpliterators { + + private TSpliterators() { + } + + public static TSpliterator spliterator(Object[] array, int additionalCharacteristics) { + return new TSpliterator() { + private int index; + + @Override + public boolean tryAdvance(Consumer action) { + if (index >= array.length) { + return false; + } + + action.accept((T) array[index]); + index++; + return true; + } + + @Override + public TSpliterator trySplit() { + return null; + } + + @Override + public long estimateSize() { + return array.length; + } + + @Override + public int characteristics() { + return additionalCharacteristics | TSpliterator.SIZED; + } + }; + } + + public static TSpliterator spliterator(Collection c, int characteristics) { + return ((TCollection) c).spliterator(); + } + + public static TSpliterator.OfInt spliterator(int[] array, int additionalCharacteristics) { + return spliterator(array, 0, array.length, additionalCharacteristics); + } + + public static TSpliterator.OfInt spliterator(int[] array, int fromIndex, int toIndex, + int additionalCharacteristics) { + return new TSpliterator.OfInt() { + int index = fromIndex; + + @Override + public TSpliterator.OfInt trySplit() { + return null; + } + + @Override + public boolean tryAdvance(IntConsumer action) { + if (index < toIndex) { + action.accept(array[index]); + index++; + return true; + } else { + return false; + } + } + }; + } + + public static TSpliterator spliterator(Iterator iterator, + long size, int characteristics) { + return new TSpliterator() { + @Override + public boolean tryAdvance(Consumer action) { + if (iterator.hasNext()) { + action.accept(iterator.next()); + return true; + } else { + return false; + } + } + + @Override + public TSpliterator trySplit() { + return null; + } + + @Override + public long estimateSize() { + return size; + } + + @Override + public int characteristics() { + return characteristics; + } + }; + } +} diff --git a/classlib/src/test/java/org/teavm/classlib/java/util/SpliteratorsTest.java b/classlib/src/test/java/org/teavm/classlib/java/util/SpliteratorsTest.java new file mode 100644 index 000000000..a5c786e09 --- /dev/null +++ b/classlib/src/test/java/org/teavm/classlib/java/util/SpliteratorsTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.classlib.java.util; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.IntConsumer; + +import org.junit.Test; + +public class SpliteratorsTest { + + @Test + public void intSpliterator() { + int[] values = {1, 2, 3, 4, 5}; + + TSpliterator.OfInt spliterator = TSpliterators.spliterator(values, 0, 5, 0); + + List collected = new ArrayList<>(); + IntConsumer collector = value -> collected.add((Integer) value); + + assertTrue(spliterator.tryAdvance(collector)); + assertTrue(spliterator.tryAdvance(collector)); + assertTrue(spliterator.tryAdvance(collector)); + assertTrue(spliterator.tryAdvance(collector)); + assertTrue(spliterator.tryAdvance(collector)); + assertFalse(spliterator.tryAdvance(collector)); + + assertEquals(Arrays.asList(1, 2, 3, 4, 5), collected); + } + + @Test + public void intSpliteratorWithSubRange() { + int[] values = {1, 2, 3, 4, 5}; + + TSpliterator.OfInt spliterator = TSpliterators.spliterator(values, 1, 4, 0); + + List collected = new ArrayList<>(); + IntConsumer collector = value -> collected.add((Integer) value); + + assertTrue(spliterator.tryAdvance(collector)); + assertTrue(spliterator.tryAdvance(collector)); + assertTrue(spliterator.tryAdvance(collector)); + assertFalse(spliterator.tryAdvance(collector)); + + assertEquals(Arrays.asList(2, 3, 4), collected); + } + + @Test + public void spliteratorFromIterator() { + List values = Arrays.asList(1, 2, 3); + + TSpliterator spliterator = TSpliterators.spliterator(values.iterator(), + values.size(), 0); + + assertEquals(3L, spliterator.estimateSize()); + } + + @Test + public void spliteratorFromObjectArray() { + Object[] array = {1, 2, 3, 4}; + + TSpliterator spliterator = TSpliterators.spliterator(array, 0); + + List collected = new ArrayList<>(); + Consumer collector = value -> collected.add(value); + + spliterator.tryAdvance(collector); + spliterator.tryAdvance(collector); + array[2] = 9; + spliterator.tryAdvance(collector); + spliterator.tryAdvance(collector); + spliterator.tryAdvance(collector); + + assertArrayEquals(new Object[] {1, 2, 9, 4}, array); + assertEquals(4L, spliterator.estimateSize()); + } +}