mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Implements some of JVM class library
This commit is contained in:
parent
1355e211e3
commit
c244c596c9
|
@ -2,24 +2,25 @@ package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
import org.teavm.classlib.java.lang.io.TSerializable;
|
import org.teavm.classlib.java.lang.io.TSerializable;
|
||||||
import org.teavm.classlib.java.util.TArrays;
|
import org.teavm.classlib.java.util.TArrays;
|
||||||
|
import org.teavm.javascript.ni.Rename;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
class AbstractStringBuilder extends TObject implements TSerializable {
|
class TAbstractStringBuilder extends TObject implements TSerializable {
|
||||||
private char[] buffer;
|
private char[] buffer;
|
||||||
private int length;
|
private int length;
|
||||||
|
|
||||||
public AbstractStringBuilder() {
|
public TAbstractStringBuilder() {
|
||||||
this(16);
|
this(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractStringBuilder(int capacity) {
|
public TAbstractStringBuilder(int capacity) {
|
||||||
buffer = new char[capacity];
|
buffer = new char[capacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractStringBuilder append(TString string) {
|
protected TAbstractStringBuilder append(TString string) {
|
||||||
ensureCapacity(length + string.length());
|
ensureCapacity(length + string.length());
|
||||||
int j = length;
|
int j = length;
|
||||||
for (int i = 0; i < string.length(); ++i) {
|
for (int i = 0; i < string.length(); ++i) {
|
||||||
|
@ -29,13 +30,20 @@ class AbstractStringBuilder extends TObject implements TSerializable {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractStringBuilder append(int value) {
|
protected TAbstractStringBuilder append(int value) {
|
||||||
|
boolean positive = true;
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
append('-');
|
positive = false;
|
||||||
value = -value;
|
value = -value;
|
||||||
}
|
}
|
||||||
if (value < 10) {
|
if (value < 10) {
|
||||||
append((char)('0' + value));
|
if (!positive) {
|
||||||
|
ensureCapacity(length + 2);
|
||||||
|
buffer[length++] = '-';
|
||||||
|
} else {
|
||||||
|
ensureCapacity(length + 1);
|
||||||
|
}
|
||||||
|
buffer[length++] = (char)('0' + value);
|
||||||
} else {
|
} else {
|
||||||
int pos = 10;
|
int pos = 10;
|
||||||
int sz = 1;
|
int sz = 1;
|
||||||
|
@ -43,7 +51,14 @@ class AbstractStringBuilder extends TObject implements TSerializable {
|
||||||
pos *= 10;
|
pos *= 10;
|
||||||
++sz;
|
++sz;
|
||||||
}
|
}
|
||||||
|
if (!positive) {
|
||||||
|
++sz;
|
||||||
|
}
|
||||||
ensureCapacity(length + sz);
|
ensureCapacity(length + sz);
|
||||||
|
if (!positive) {
|
||||||
|
buffer[length++] = '-';
|
||||||
|
}
|
||||||
|
pos /= 10;
|
||||||
while (pos > 0) {
|
while (pos > 0) {
|
||||||
buffer[length++] = (char)('0' + value / pos);
|
buffer[length++] = (char)('0' + value / pos);
|
||||||
value %= pos;
|
value %= pos;
|
||||||
|
@ -53,7 +68,7 @@ class AbstractStringBuilder extends TObject implements TSerializable {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractStringBuilder append(char c) {
|
protected TAbstractStringBuilder append(char c) {
|
||||||
ensureCapacity(length + 1);
|
ensureCapacity(length + 1);
|
||||||
buffer[length++] = c;
|
buffer[length++] = c;
|
||||||
return this;
|
return this;
|
||||||
|
@ -65,4 +80,10 @@ class AbstractStringBuilder extends TObject implements TSerializable {
|
||||||
}
|
}
|
||||||
buffer = TArrays.copyOf(buffer, capacity * 2 + 1);
|
buffer = TArrays.copyOf(buffer, capacity * 2 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Rename("toString")
|
||||||
|
public TString toString0() {
|
||||||
|
return new TString(buffer, 0, length);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public final class TMath extends TObject {
|
||||||
|
private TMath() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int min(int a, int b) {
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import org.teavm.javascript.ni.GeneratedBy;
|
||||||
*/
|
*/
|
||||||
public class TString extends TObject implements TSerializable {
|
public class TString extends TObject implements TSerializable {
|
||||||
private char[] characters;
|
private char[] characters;
|
||||||
|
private transient int hashCode;
|
||||||
|
|
||||||
public TString() {
|
public TString() {
|
||||||
this.characters = new char[0];
|
this.characters = new char[0];
|
||||||
|
@ -47,6 +48,41 @@ public class TString extends TObject implements TSerializable {
|
||||||
return new TStringBuilder().append(index).toString0();
|
return new TStringBuilder().append(index).toString0();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(TObject other) {
|
||||||
|
if (this == other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(other instanceof TString)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TString str = (TString)other;
|
||||||
|
if (str.length() != length()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < str.length(); ++i) {
|
||||||
|
if (charAt(i) != str.charAt(i)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if (hashCode == 0) {
|
||||||
|
hashCode ^= 734262231;
|
||||||
|
for (char c : characters) {
|
||||||
|
hashCode = (hashCode << 4) | (hashCode >>> 28);
|
||||||
|
hashCode ^= 347236277 ^ c;
|
||||||
|
if (hashCode == 0) {
|
||||||
|
++hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
@GeneratedBy(StringNativeGenerator.class)
|
@GeneratedBy(StringNativeGenerator.class)
|
||||||
public static native TString wrap(String str);
|
public static native TString wrap(String str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ package org.teavm.classlib.java.lang;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class TStringBuilder extends AbstractStringBuilder {
|
public class TStringBuilder extends TAbstractStringBuilder {
|
||||||
@Override
|
@Override
|
||||||
public TStringBuilder append(TString string) {
|
public TStringBuilder append(TString string) {
|
||||||
super.append(string);
|
super.append(string);
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
class TStringBuilderTests {
|
||||||
|
@Test
|
||||||
|
public void integerAppended() {
|
||||||
|
TStringBuilder sb = new TStringBuilder();
|
||||||
|
sb.append(23);
|
||||||
|
assertEquals("23", sb.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,8 @@ public class ClasslibTestGenerator {
|
||||||
private static Renderer renderer;
|
private static Renderer renderer;
|
||||||
private static List<MethodReference> testMethods = new ArrayList<>();
|
private static List<MethodReference> testMethods = new ArrayList<>();
|
||||||
private static Map<String, List<MethodReference>> groupedMethods = new HashMap<>();
|
private static Map<String, List<MethodReference>> groupedMethods = new HashMap<>();
|
||||||
private static String[] testClasses = { "java.lang.ObjectTests", "java.lang.SystemTests" };
|
private static String[] testClasses = { "java.lang.ObjectTests", "java.lang.SystemTests",
|
||||||
|
"java.lang.StringBuilderTests" };
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
out = System.out;
|
out = System.out;
|
||||||
|
|
|
@ -159,10 +159,20 @@ public class DependencyChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodGraph createMethodGraph(MethodReference methodRef) {
|
private MethodGraph createMethodGraph(final MethodReference methodRef) {
|
||||||
initClass(methodRef.getClassName());
|
initClass(methodRef.getClassName());
|
||||||
ClassHolder cls = classSource.getClassHolder(methodRef.getClassName());
|
ClassHolder cls = classSource.getClassHolder(methodRef.getClassName());
|
||||||
MethodHolder method = cls.getMethod(methodRef.getDescriptor());
|
MethodHolder method = cls.getMethod(methodRef.getDescriptor());
|
||||||
|
if (method == null) {
|
||||||
|
while (cls != null) {
|
||||||
|
method = cls.getMethod(methodRef.getDescriptor());
|
||||||
|
if (method != null) {
|
||||||
|
return methodCache.map(new MethodReference(cls.getName(), methodRef.getDescriptor()));
|
||||||
|
}
|
||||||
|
cls = classSource.getClassHolder(cls.getParent());
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Method not found: " + methodRef);
|
||||||
|
}
|
||||||
ValueType[] arguments = method.getParameterTypes();
|
ValueType[] arguments = method.getParameterTypes();
|
||||||
int paramCount = arguments.length + 1;
|
int paramCount = arguments.length + 1;
|
||||||
int varCount = Math.max(paramCount, method.getProgram().variableCount());
|
int varCount = Math.max(paramCount, method.getProgram().variableCount());
|
||||||
|
@ -184,10 +194,15 @@ public class DependencyChecker {
|
||||||
method.getName() + MethodDescriptor.get(method) + ":RESULT");
|
method.getName() + MethodDescriptor.get(method) + ":RESULT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MethodGraph graph = new MethodGraph(parameterNodes, paramCount, resultNode, this);
|
final MethodGraph graph = new MethodGraph(parameterNodes, paramCount, resultNode, this);
|
||||||
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(this);
|
final MethodHolder currentMethod = method;
|
||||||
graphBuilder.buildGraph(method, graph);
|
executor.submit(new Runnable() {
|
||||||
achieveClass(methodRef.getClassName());
|
@Override public void run() {
|
||||||
|
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
|
||||||
|
graphBuilder.buildGraph(currentMethod, graph);
|
||||||
|
achieveClass(methodRef.getClassName());
|
||||||
|
}
|
||||||
|
});
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +238,9 @@ public class DependencyChecker {
|
||||||
private void activateDependencyPlugin(MethodReference methodRef) {
|
private void activateDependencyPlugin(MethodReference methodRef) {
|
||||||
ClassHolder cls = classSource.getClassHolder(methodRef.getClassName());
|
ClassHolder cls = classSource.getClassHolder(methodRef.getClassName());
|
||||||
MethodHolder method = cls.getMethod(methodRef.getDescriptor());
|
MethodHolder method = cls.getMethod(methodRef.getDescriptor());
|
||||||
|
if (method == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
AnnotationHolder depAnnot = method.getAnnotations().get(PluggableDependency.class.getName());
|
AnnotationHolder depAnnot = method.getAnnotations().get(PluggableDependency.class.getName());
|
||||||
if (depAnnot == null) {
|
if (depAnnot == null) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -98,5 +98,6 @@ public class ClassHolder extends ElementHolder {
|
||||||
field.getName() + " is not a member of " + getName());
|
field.getName() + " is not a member of " + getName());
|
||||||
}
|
}
|
||||||
fields.remove(field.getName());
|
fields.remove(field.getName());
|
||||||
|
field.setOwner(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user