From 1355e211e36dfff5264670241cfff830b22f3c28 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 25 Nov 2013 17:41:18 +0400 Subject: [PATCH] Implementing class library emulation --- .../java/lang/AbstractStringBuilder.java | 68 +++++++++++++++++++ .../teavm/classlib/java/lang/TException.java | 16 +++++ .../java/lang/TIllegalArgumentException.java | 25 +++++++ .../java/lang/TIllegalStateException.java | 25 +++++++ .../java/lang/TIndexOutOfBoundsException.java | 17 +++++ .../classlib/java/lang/TRuntimeException.java | 28 ++++++++ .../org/teavm/classlib/java/lang/TString.java | 18 ++++- .../classlib/java/lang/TStringBuilder.java | 19 ++++++ .../TStringIndexOutOfBoundsException.java | 21 ++++++ .../teavm/classlib/java/lang/TThrowable.java | 63 ++++++++++++++++- .../classlib/java/lang/io/TSerializable.java | 8 +++ .../org/teavm/classlib/java/util/TArrays.java | 18 +++++ .../java/org/teavm/javascript/ni/Remove.java | 15 ++++ 13 files changed, 339 insertions(+), 2 deletions(-) create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/AbstractStringBuilder.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalArgumentException.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalStateException.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIndexOutOfBoundsException.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TRuntimeException.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringBuilder.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringIndexOutOfBoundsException.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TSerializable.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrays.java create mode 100644 teavm-core/src/main/java/org/teavm/javascript/ni/Remove.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/AbstractStringBuilder.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/AbstractStringBuilder.java new file mode 100644 index 000000000..0e75edcd3 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/AbstractStringBuilder.java @@ -0,0 +1,68 @@ +package org.teavm.classlib.java.lang; + +import org.teavm.classlib.java.lang.io.TSerializable; +import org.teavm.classlib.java.util.TArrays; + +/** + * + * @author Alexey Andreev + */ +class AbstractStringBuilder extends TObject implements TSerializable { + private char[] buffer; + private int length; + + public AbstractStringBuilder() { + this(16); + } + + public AbstractStringBuilder(int capacity) { + buffer = new char[capacity]; + } + + protected AbstractStringBuilder append(TString string) { + ensureCapacity(length + string.length()); + int j = length; + for (int i = 0; i < string.length(); ++i) { + buffer[j++] = string.charAt(i); + } + length = j; + return this; + } + + protected AbstractStringBuilder append(int value) { + if (value < 0) { + append('-'); + value = -value; + } + if (value < 10) { + append((char)('0' + value)); + } else { + int pos = 10; + int sz = 1; + while (pos <= 1000000000 && pos <= value) { + pos *= 10; + ++sz; + } + ensureCapacity(length + sz); + while (pos > 0) { + buffer[length++] = (char)('0' + value / pos); + value %= pos; + pos /= 10; + } + } + return this; + } + + protected AbstractStringBuilder append(char c) { + ensureCapacity(length + 1); + buffer[length++] = c; + return this; + } + + private void ensureCapacity(int capacity) { + if (buffer.length >= capacity) { + return; + } + buffer = TArrays.copyOf(buffer, capacity * 2 + 1); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TException.java index 21151a6fd..ee69a6453 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TException.java @@ -6,4 +6,20 @@ package org.teavm.classlib.java.lang; */ public class TException extends TThrowable { private static final long serialVersionUID = -2188339106250208952L; + + public TException() { + super(); + } + + public TException(TString message, TThrowable cause) { + super(message, cause); + } + + public TException(TString message) { + super(message); + } + + public TException(TThrowable cause) { + super(cause); + } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalArgumentException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalArgumentException.java new file mode 100644 index 000000000..24e848749 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalArgumentException.java @@ -0,0 +1,25 @@ +package org.teavm.classlib.java.lang; + +/** + * + * @author Alexey Andreev + */ +public class TIllegalArgumentException extends TRuntimeException { + private static final long serialVersionUID = -1225768288500984373L; + + public TIllegalArgumentException() { + super(); + } + + public TIllegalArgumentException(TString message, TThrowable cause) { + super(message, cause); + } + + public TIllegalArgumentException(TString message) { + super(message); + } + + public TIllegalArgumentException(TThrowable cause) { + super(cause); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalStateException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalStateException.java new file mode 100644 index 000000000..6b3553749 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalStateException.java @@ -0,0 +1,25 @@ +package org.teavm.classlib.java.lang; + +/** + * + * @author Alexey Andreev + */ +public class TIllegalStateException extends TException { + private static final long serialVersionUID = 218741044430713159L; + + public TIllegalStateException() { + super(); + } + + public TIllegalStateException(TString message, TThrowable cause) { + super(message, cause); + } + + public TIllegalStateException(TString message) { + super(message); + } + + public TIllegalStateException(TThrowable cause) { + super(cause); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIndexOutOfBoundsException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIndexOutOfBoundsException.java new file mode 100644 index 000000000..264bb5f63 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIndexOutOfBoundsException.java @@ -0,0 +1,17 @@ +package org.teavm.classlib.java.lang; + +/** + * + * @author Alexey Andreev + */ +public class TIndexOutOfBoundsException extends TRuntimeException { + private static final long serialVersionUID = -7329782331640782287L; + + public TIndexOutOfBoundsException() { + super(); + } + + public TIndexOutOfBoundsException(TString message) { + super(message); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TRuntimeException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TRuntimeException.java new file mode 100644 index 000000000..5272c7f4f --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TRuntimeException.java @@ -0,0 +1,28 @@ +package org.teavm.classlib.java.lang; + +import org.teavm.javascript.ni.Superclass; + +/** + * + * @author Alexey Andreev + */ +@Superclass("java.lang.Exception") +public class TRuntimeException extends TException { + private static final long serialVersionUID = 3506083061304642891L; + + public TRuntimeException() { + super(); + } + + public TRuntimeException(TString message, TThrowable cause) { + super(message, cause); + } + + public TRuntimeException(TString message) { + super(message); + } + + public TRuntimeException(TThrowable cause) { + super(cause); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java index abd5121e6..7474827ec 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java @@ -1,12 +1,13 @@ package org.teavm.classlib.java.lang; +import org.teavm.classlib.java.lang.io.TSerializable; import org.teavm.javascript.ni.GeneratedBy; /** * * @author Alexey Andreev */ -public class TString extends TObject { +public class TString extends TObject implements TSerializable { private char[] characters; public TString() { @@ -31,6 +32,21 @@ public class TString extends TObject { } } + public char charAt(int index) { + if (index < 0 || index >= characters.length) { + throw new StringIndexOutOfBoundsException(null); + } + return characters[index]; + } + + public int length() { + return characters.length; + } + + public static TString valueOf(int index) { + return new TStringBuilder().append(index).toString0(); + } + @GeneratedBy(StringNativeGenerator.class) public static native TString wrap(String str); } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringBuilder.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringBuilder.java new file mode 100644 index 000000000..50dae2324 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringBuilder.java @@ -0,0 +1,19 @@ +package org.teavm.classlib.java.lang; + +/** + * + * @author Alexey Andreev + */ +public class TStringBuilder extends AbstractStringBuilder { + @Override + public TStringBuilder append(TString string) { + super.append(string); + return this; + } + + @Override + public TStringBuilder append(int value) { + super.append(value); + return this; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringIndexOutOfBoundsException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringIndexOutOfBoundsException.java new file mode 100644 index 000000000..f2cbbdd85 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStringIndexOutOfBoundsException.java @@ -0,0 +1,21 @@ +package org.teavm.classlib.java.lang; + +/** + * + * @author Alexey Andreev + */ +public class TStringIndexOutOfBoundsException extends TIndexOutOfBoundsException { + private static final long serialVersionUID = 6706349858694463085L; + + public TStringIndexOutOfBoundsException() { + super(); + } + + public TStringIndexOutOfBoundsException(TString message) { + super(message); + } + + public TStringIndexOutOfBoundsException(int index) { + super(new TStringBuilder().append(TString.wrap("String index out of bounds: ")).append(index).toString0()); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java index 3ec6f954b..452daccf9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java @@ -1,11 +1,72 @@ package org.teavm.classlib.java.lang; +import org.teavm.javascript.ni.Remove; +import org.teavm.javascript.ni.Rename; +import org.teavm.javascript.ni.Superclass; + /** * * @author Alexey Andreev */ -public class TThrowable extends Throwable { +@Superclass("java.lang.Object") +public class TThrowable extends RuntimeException { private static final long serialVersionUID = 2026791432677149320L; private TString message; private TThrowable cause; + + public TThrowable() { + fillInStackTrace(); + } + + public TThrowable(TString message) { + fillInStackTrace(); + this.message = message; + } + + public TThrowable(TString message, TThrowable cause) { + fillInStackTrace(); + this.message = message; + this.cause = cause; + } + + public TThrowable(TThrowable cause) { + this.cause = cause; + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + + @Rename("getMessage") + public TString getMessage0() { + return message; + } + + @Rename("getLocalizedMessage") + public TString getLocalizedMessage0() { + return getMessage0(); + } + + @Override + public synchronized TThrowable getCause() { + return cause != this ? cause : null; + } + + @Remove + public native TClass getClass0(); + + @Remove + public native TString toString0(); + + public synchronized TThrowable initCause(TThrowable cause) { + if (this.cause != this && this.cause != null) { + throw new TIllegalStateException(TString.wrap("Cause already set")); + } + if (cause == this) { + throw new TIllegalArgumentException(TString.wrap("Circular causation relation")); + } + this.cause = cause; + return this; + } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TSerializable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TSerializable.java new file mode 100644 index 000000000..33a11b51e --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TSerializable.java @@ -0,0 +1,8 @@ +package org.teavm.classlib.java.lang.io; + +/** + * + * @author Alexey Andreev + */ +public interface TSerializable { +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrays.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrays.java new file mode 100644 index 000000000..b2104b33a --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrays.java @@ -0,0 +1,18 @@ +package org.teavm.classlib.java.util; + +import org.teavm.classlib.java.lang.TObject; + +/** + * + * @author Alexey Andreev + */ +public class TArrays extends TObject { + public static char[] copyOf(char[] array, int length) { + char[] result = new char[length]; + int sz = Math.min(length, array.length); + for (int i = 0; i < sz; ++i) { + result[i] = array[i]; + } + return result; + } +} diff --git a/teavm-core/src/main/java/org/teavm/javascript/ni/Remove.java b/teavm-core/src/main/java/org/teavm/javascript/ni/Remove.java new file mode 100644 index 000000000..c613bdd65 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/ni/Remove.java @@ -0,0 +1,15 @@ +package org.teavm.javascript.ni; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @author Alexey Andreev + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Remove { +}