mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds java.lang.String methods. Makes intern on all string constants.
This commit is contained in:
parent
e8fc894bc9
commit
91a7a9ba22
|
@ -19,6 +19,9 @@ import org.teavm.classlib.impl.charset.*;
|
|||
import org.teavm.classlib.java.io.TSerializable;
|
||||
import org.teavm.classlib.java.io.TUnsupportedEncodingException;
|
||||
import org.teavm.classlib.java.util.TArrays;
|
||||
import org.teavm.classlib.java.util.TComparator;
|
||||
import org.teavm.classlib.java.util.THashMap;
|
||||
import org.teavm.classlib.java.util.TMap;
|
||||
import org.teavm.dependency.PluggableDependency;
|
||||
import org.teavm.javascript.ni.InjectedBy;
|
||||
import org.teavm.javascript.ni.Rename;
|
||||
|
@ -28,8 +31,14 @@ import org.teavm.javascript.ni.Rename;
|
|||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class TString extends TObject implements TSerializable, TComparable<TString>, TCharSequence {
|
||||
public static final TComparator<TString> CASE_INSENSITIVE_ORDER = new TComparator<TString>() {
|
||||
@Override public int compare(TString o1, TString o2) {
|
||||
return o1.compareToIgnoreCase(o2);
|
||||
}
|
||||
};
|
||||
private char[] characters;
|
||||
private transient int hashCode;
|
||||
private static TMap<TString, TString> pool = new THashMap<>();
|
||||
|
||||
public TString() {
|
||||
this.characters = new char[0];
|
||||
|
@ -183,6 +192,21 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
|
|||
return length() - anotherString.length();
|
||||
}
|
||||
|
||||
public int compareToIgnoreCase(TString anotherString) {
|
||||
if (this == anotherString) {
|
||||
return 0;
|
||||
}
|
||||
int l = TMath.min(length(), anotherString.length());
|
||||
for (int i = 0; i < l; ++i) {
|
||||
char a = TCharacter.toLowerCase(charAt(i));
|
||||
char b = TCharacter.toLowerCase(anotherString.charAt(i));
|
||||
if (a - b != 0) {
|
||||
return a - b;
|
||||
}
|
||||
}
|
||||
return length() - anotherString.length();
|
||||
}
|
||||
|
||||
public boolean startsWith(TString prefix, int toffset) {
|
||||
if (toffset + prefix.length() > length()) {
|
||||
return false;
|
||||
|
@ -548,4 +572,32 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
|
|||
}
|
||||
return new TString(codePoints, 0, codePointCount);
|
||||
}
|
||||
|
||||
public TString toUpperCase() {
|
||||
if (isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
int[] codePoints = new int[characters.length];
|
||||
int codePointCount = 0;
|
||||
for (int i = 0; i < characters.length; ++i) {
|
||||
if (i == characters.length - 1 || !UTF16Helper.isHighSurrogate(characters[i]) ||
|
||||
!UTF16Helper.isLowSurrogate(characters[i + 1])) {
|
||||
codePoints[codePointCount++] = TCharacter.toUpperCase(characters[i]);
|
||||
} else {
|
||||
codePoints[codePointCount++] = TCharacter.toUpperCase(UTF16Helper.buildCodePoint(
|
||||
characters[i], characters[i + 1]));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return new TString(codePoints, 0, codePointCount);
|
||||
}
|
||||
|
||||
public TString intern() {
|
||||
TString interned = pool.get(this);
|
||||
if (interned == null) {
|
||||
interned = this;
|
||||
pool.put(interned, interned);
|
||||
}
|
||||
return interned;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,4 +290,14 @@ public class StringTest {
|
|||
public void makesLowerCase() {
|
||||
assertEquals("foo bar", "FoO bAr".toLowerCase());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interns() {
|
||||
assertSame(("ab" + "c").intern(), ("a" + "bc").intern());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void internsConstants() {
|
||||
assertSame("abc", ("a" + "bc").intern());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ import org.teavm.model.*;
|
|||
* @author Alexey Andreev
|
||||
*/
|
||||
public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext {
|
||||
private static final MethodReference internRef = new MethodReference("java.lang.String", "intern",
|
||||
ValueType.object("java.lang.String"));
|
||||
private static final String variableNames = "abcdefghijkmnopqrstuvwxyz";
|
||||
private NamingStrategy naming;
|
||||
private SourceWriter writer;
|
||||
|
@ -930,7 +932,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
ValueType type = (ValueType)cst;
|
||||
return "$rt_cls(" + typeToClsString(naming, type) + ")";
|
||||
} else if (cst instanceof String) {
|
||||
return "$rt_str(\"" + escapeString((String)cst) + "\")";
|
||||
return naming.getFullNameFor(internRef) + "($rt_str(\"" + escapeString((String)cst) + "\"))";
|
||||
} else if (cst instanceof Long) {
|
||||
long value = (Long)cst;
|
||||
if (value == 0) {
|
||||
|
|
|
@ -174,6 +174,10 @@ public class TeaVM implements TeaVMHost {
|
|||
dependencyChecker.linkMethod(new MethodReference("java.lang.String", "getChars",
|
||||
ValueType.INTEGER, ValueType.INTEGER, ValueType.arrayOf(ValueType.CHARACTER), ValueType.INTEGER,
|
||||
ValueType.VOID), DependencyStack.ROOT).use();
|
||||
MethodDependency internDep = dependencyChecker.linkMethod(new MethodReference("java.lang.String", "intern",
|
||||
ValueType.object("java.lang.String")), DependencyStack.ROOT);
|
||||
internDep.getVariable(0).propagate("java.lang.String");
|
||||
internDep.use();
|
||||
dependencyChecker.linkMethod(new MethodReference("java.lang.String", "length", ValueType.INTEGER),
|
||||
DependencyStack.ROOT).use();
|
||||
dependencyChecker.linkMethod(new MethodReference("java.lang.Object", new MethodDescriptor("clone",
|
||||
|
|
Loading…
Reference in New Issue
Block a user