Skip to content

Commit a8e31dc

Browse files
committed
More emulation
1 parent b780d3f commit a8e31dc

File tree

33 files changed

+968
-102
lines changed

33 files changed

+968
-102
lines changed

dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public class JavaResourceBase {
8282
"public interface CharSequence {",
8383
" char charAt(int index);",
8484
" int length();",
85+
" default boolean isEmpty() { return length() == 0; }",
8586
" String toString();",
8687
"}");
8788

user/super/com/google/gwt/emul/java/lang/CharSequence.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,38 @@ public boolean hasNext() {
5858
}, Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED, false);
5959
}
6060

61+
default IntStream codePoints() {
62+
return StreamSupport.intStream(() -> {
63+
PrimitiveIterator.OfInt it = new PrimitiveIterator.OfInt() {
64+
int cursor;
65+
66+
@Override
67+
public int nextInt() {
68+
checkElement(hasNext());
69+
int codePoint = CharSequence.this.toString().codePointAt(cursor++);
70+
if (codePoint >= 1 << 16) {
71+
cursor++;
72+
}
73+
return codePoint;
74+
}
75+
76+
@Override
77+
public boolean hasNext() {
78+
return cursor < length();
79+
}
80+
};
81+
return Spliterators.spliterator(it, length(), Spliterator.ORDERED);
82+
}, Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED, false);
83+
}
84+
85+
default boolean isEmpty() {
86+
return length() == 0;
87+
}
88+
89+
static int compare(CharSequence cs1, CharSequence cs2) {
90+
return cs1.toString().compareTo(cs2.toString());
91+
}
92+
6193
// CHECKSTYLE_OFF: Utility methods.
6294
@JsMethod
6395
static boolean $isInstance(HasCharSequenceTypeMarker instance) {

user/super/com/google/gwt/emul/java/lang/String.java

Lines changed: 130 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@
2727
import java.nio.charset.Charset;
2828
import java.nio.charset.UnsupportedCharsetException;
2929
import java.util.Comparator;
30+
import java.util.List;
3031
import java.util.Locale;
3132
import java.util.Spliterator;
3233
import java.util.Spliterators;
3334
import java.util.StringJoiner;
3435
import java.util.function.Consumer;
36+
import java.util.function.Function;
37+
import java.util.stream.Collectors;
3538
import java.util.stream.Stream;
3639
import java.util.stream.StreamSupport;
3740
import javaemul.internal.ArrayHelper;
@@ -488,6 +491,7 @@ public String intern() {
488491
return checkNotNull(this);
489492
}
490493

494+
@Override
491495
public boolean isEmpty() {
492496
return length() == 0;
493497
}
@@ -815,6 +819,126 @@ private int getTrailingWhitespaceLength() {
815819
return length;
816820
}
817821

822+
public String indent(int spaces) {
823+
if (spaces == 0) {
824+
return this;
825+
}
826+
Stream<String> indentedLines;
827+
if (spaces > 0) {
828+
String spaceString = " ".repeat(spaces);
829+
indentedLines = lines().map(line -> spaceString + line);
830+
} else {
831+
indentedLines = lines().map(
832+
line -> line.substring(Math.min(-spaces, line.getLeadingWhitespaceLength())));
833+
}
834+
return indentedLines.collect(Collectors.joining("\n", "", "\n"));
835+
}
836+
837+
public String stripIndent() {
838+
if (isEmpty()) {
839+
return "";
840+
}
841+
List<String> lines = lines().collect(Collectors.toList());
842+
int minIndent;
843+
char lastChar = charAt(length() - 1);
844+
String suffix = "";
845+
if (lastChar != '\r' && lastChar != '\n') {
846+
minIndent = Integer.MAX_VALUE;
847+
for (int i = 0; i < lines.size() - 1; i++) {
848+
String line = lines.get(i);
849+
int leadingWhitespace = line.getLeadingWhitespaceLength();
850+
// only update minIndent if not blank
851+
if (leadingWhitespace < line.length()) {
852+
minIndent = Math.min(minIndent, leadingWhitespace);
853+
}
854+
}
855+
// the last line affects minIndent even if blank
856+
minIndent = Math.min(minIndent, lines.get(lines.size() - 1).getLeadingWhitespaceLength());
857+
suffix = "\n";
858+
} else {
859+
minIndent = 0;
860+
}
861+
final int outdent = minIndent;
862+
return lines.stream().map(line -> {
863+
if (line.isBlank()) {
864+
return "";
865+
}
866+
return line.substring(outdent).stripTrailing();
867+
})
868+
.collect(Collectors.joining("\n", "", suffix));
869+
}
870+
871+
public String translateEscapes() {
872+
StringBuilder result = new StringBuilder();
873+
int translated = 0;
874+
while (translated < length()) {
875+
int nextBackslash = indexOf("\\", translated);
876+
if (nextBackslash == -1) {
877+
result.append(substring(translated));
878+
return result.toString();
879+
}
880+
if (nextBackslash == length() - 1) {
881+
throw new IllegalArgumentException();
882+
}
883+
result.append(substring(translated, nextBackslash));
884+
char currentChar = charAt(nextBackslash + 1);
885+
translated = nextBackslash + 2;
886+
switch (currentChar) {
887+
case 'b':
888+
result.append('\b');
889+
break;
890+
case 's':
891+
result.append(' ');
892+
break;
893+
case 't':
894+
result.append('\t');
895+
break;
896+
case 'n':
897+
result.append('\n');
898+
break;
899+
case 'f':
900+
result.append('\f');
901+
break;
902+
case 'r':
903+
result.append('\r');
904+
break;
905+
case '\n':
906+
case '\r':
907+
// discard
908+
break;
909+
case '"':
910+
result.append('"');
911+
break;
912+
case '\'':
913+
result.append('\'');
914+
break;
915+
case '\\':
916+
result.append('\\');
917+
break;
918+
case '0':
919+
case '1':
920+
case '2':
921+
case '3':
922+
case '4':
923+
case '5':
924+
case '6':
925+
case '7':
926+
int unicode = currentChar - '0';
927+
char nextChar = charAt(translated);
928+
while (nextChar >= '0' && nextChar < '8' && unicode < 32) {
929+
unicode = (unicode << 3) + (nextChar - '0');
930+
translated++;
931+
nextChar = translated < length() ? charAt(translated) : 0;
932+
}
933+
result.append((char) unicode);
934+
break;
935+
default:
936+
throw new IllegalArgumentException();
937+
}
938+
}
939+
return result.toString();
940+
}
941+
818942
private class LinesSpliterator extends Spliterators.AbstractSpliterator<String> {
819943
private int nextIndex = 0;
820944
private int rPosition = -1;
@@ -830,10 +954,10 @@ public boolean tryAdvance(Consumer<? super String> action) {
830954
return false;
831955
}
832956
if (rPosition < nextIndex) {
833-
rPosition = cappedIndexOf('\r');
957+
rPosition = cappedIndexOf('\r', nextIndex);
834958
}
835959
if (nPosition < nextIndex) {
836-
nPosition = cappedIndexOf('\n');
960+
nPosition = cappedIndexOf('\n', nextIndex);
837961
}
838962
int lineEnd = Math.min(nPosition, rPosition);
839963
action.accept(substring(nextIndex, lineEnd));
@@ -843,11 +967,11 @@ public boolean tryAdvance(Consumer<? super String> action) {
843967
}
844968
return nextIndex < length();
845969
}
970+
}
846971

847-
private int cappedIndexOf(char c) {
848-
int index = indexOf(c, nextIndex);
849-
return index == -1 ? length() : index;
850-
}
972+
private int cappedIndexOf(char c, int nextIndex) {
973+
int index = indexOf(c, nextIndex);
974+
return index == -1 ? length() : index;
851975
}
852976

853977
@JsType(isNative = true, name = "String", namespace = "<window>")

user/super/com/google/gwt/emul/java/util/BitSet.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
import javaemul.internal.ArrayHelper;
2222
import javaemul.internal.LongUtils;
2323

24+
import java.util.function.IntConsumer;
25+
import java.util.stream.IntStream;
26+
import java.util.stream.StreamSupport;
27+
2428
/**
2529
* This implementation uses a dense array holding bit groups of size 31 to keep track of when bits
2630
* are set to true or false. Using 31 bits keeps our implementation within the range of V8's
@@ -37,6 +41,36 @@ public class BitSet {
3741

3842
private final int[] array;
3943

44+
private class BitSetSpliterator implements Spliterator.OfInt {
45+
int nextBitIndex = 0;
46+
47+
@Override
48+
public boolean tryAdvance(IntConsumer action) {
49+
int nextBit = nextSetBit(nextBitIndex);
50+
if (nextBit >= 0) {
51+
nextBitIndex = nextBit + 1;
52+
action.accept(nextBit);
53+
return true;
54+
}
55+
return false;
56+
}
57+
58+
@Override
59+
public Spliterator.OfInt trySplit() {
60+
return null;
61+
}
62+
63+
@Override
64+
public long estimateSize() {
65+
return size();
66+
}
67+
68+
@Override
69+
public int characteristics() {
70+
return Spliterator.SIZED | Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED;
71+
}
72+
}
73+
4074
public BitSet() {
4175
array = new int[0];
4276
}
@@ -604,6 +638,11 @@ public int nextSetBit(int fromIndex) {
604638
return bitIndex(index) + Integer.numberOfTrailingZeros(word);
605639
}
606640

641+
public IntStream stream() {
642+
Spliterator.OfInt spliterator = new BitSetSpliterator();
643+
return StreamSupport.intStream(spliterator, false);
644+
}
645+
607646
public int previousClearBit(int fromIndex) {
608647
if (fromIndex == -1) {
609648
return -1;

user/super/com/google/gwt/emul/java/util/Map.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,13 @@ static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V>
276276
return (Comparator<Map.Entry<K, V>> & Serializable)
277277
(a, b) -> cmp.compare(a.getValue(), b.getValue());
278278
}
279+
280+
static <K,V> Map.Entry<K,V> copyOf(Map.Entry<? extends K,? extends V> e) {
281+
if (e instanceof AbstractMap.SimpleImmutableEntry) {
282+
return (Entry<K, V>) e;
283+
}
284+
return entry(e.getKey(), e.getValue());
285+
}
279286
}
280287

281288
void clear();

user/super/com/google/gwt/emul/java/util/stream/DoubleStream.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717

1818
import static javaemul.internal.InternalPreconditions.checkState;
1919

20+
import java.util.ArrayList;
2021
import java.util.Arrays;
2122
import java.util.DoubleSummaryStatistics;
23+
import java.util.List;
2224
import java.util.OptionalDouble;
2325
import java.util.PrimitiveIterator;
2426
import java.util.Spliterator;
@@ -58,6 +60,15 @@ default DoubleStream.Builder add(double t) {
5860
DoubleStream build();
5961
}
6062

63+
/**
64+
* See <a
65+
* href="https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/stream/DoubleStream.DoubleMapMultiConsumer.html">
66+
* the official Java API doc</a> for details.
67+
*/
68+
interface DoubleMapMultiConsumer {
69+
void accept(double value, DoubleConsumer consumer);
70+
}
71+
6172
static Builder builder() {
6273
return new Builder() {
6374
private double[] items = new double[0];
@@ -317,5 +328,13 @@ public boolean tryAdvance(DoubleConsumer action) {
317328
return StreamSupport.doubleStream(spliterator, false);
318329
}
319330

331+
default DoubleStream mapMulti(DoubleStream.DoubleMapMultiConsumer mapper) {
332+
return flatMap(element -> {
333+
List<Double> buffer = new ArrayList<>();
334+
mapper.accept(element, (DoubleConsumer) buffer::add);
335+
return buffer.stream().mapToDouble(n -> n);
336+
});
337+
}
338+
320339
double[] toArray();
321340
}

user/super/com/google/gwt/emul/java/util/stream/IntStream.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717

1818
import static javaemul.internal.InternalPreconditions.checkState;
1919

20+
import java.util.ArrayList;
2021
import java.util.Arrays;
2122
import java.util.Comparator;
2223
import java.util.IntSummaryStatistics;
24+
import java.util.List;
2325
import java.util.OptionalDouble;
2426
import java.util.OptionalInt;
2527
import java.util.PrimitiveIterator;
@@ -61,6 +63,15 @@ default IntStream.Builder add(int t) {
6163
IntStream build();
6264
}
6365

66+
/**
67+
* See <a
68+
* href="https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/stream/IntStream.IntMapMultiConsumer.html">
69+
* the official Java API doc</a> for details.
70+
*/
71+
interface IntMapMultiConsumer {
72+
void accept(int value, IntConsumer consumer);
73+
}
74+
6475
static Builder builder() {
6576
return new Builder() {
6677
private int[] items = new int[0];
@@ -366,5 +377,13 @@ public boolean tryAdvance(IntConsumer action) {
366377
return StreamSupport.intStream(spliterator, false);
367378
}
368379

380+
default IntStream mapMulti(IntMapMultiConsumer mapper) {
381+
return flatMap(element -> {
382+
List<Integer> buffer = new ArrayList<>();
383+
mapper.accept(element, (IntConsumer) buffer::add);
384+
return buffer.stream().mapToInt(n -> n);
385+
});
386+
}
387+
369388
int[] toArray();
370389
}

0 commit comments

Comments
 (0)