From f3ae632786cf48295d0c22e35e457d64020c6bd6 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 20 Feb 2014 00:53:44 +0400 Subject: [PATCH] Adds implementations of some JCL classes --- .../java/lang/ClassNativeGenerator.java | 30 ++++- .../org/teavm/classlib/java/lang/TClass.java | 14 ++- .../lang/TCloneNotSupportedException.java | 32 +++++ .../teavm/classlib/java/lang/TCloneable.java | 23 ++++ .../org/teavm/classlib/java/lang/TEnum.java | 79 ++++++++++++ .../teavm/classlib/java/lang/TIterable.java | 26 ++++ .../org/teavm/classlib/java/lang/TLong.java | 52 ++++++++ .../org/teavm/classlib/java/lang/TObject.java | 2 +- .../classlib/java/lang/TStringBuilder.java | 2 +- .../org/teavm/classlib/java/util/TArrays.java | 119 ++++++++++++++++++ .../teavm/classlib/java/util/TIterator.java | 30 +++++ .../java/util/concurrent/TCallable.java | 27 ++++ .../teavm/classlib/java/lang/ClassTest.java | 20 +++ .../java/org/teavm/javascript/Renderer.java | 4 + .../resources/org/teavm/javascript/runtime.js | 2 +- teavm-html4j/pom.xml | 4 +- 16 files changed, 459 insertions(+), 7 deletions(-) create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneNotSupportedException.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneable.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ClassNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ClassNativeGenerator.java index 80a93b2cb..914840d67 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ClassNativeGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ClassNativeGenerator.java @@ -17,6 +17,9 @@ package org.teavm.classlib.java.lang; import java.io.IOException; import org.teavm.codegen.SourceWriter; +import org.teavm.dependency.DependencyChecker; +import org.teavm.dependency.DependencyPlugin; +import org.teavm.dependency.MethodDependency; import org.teavm.javascript.ni.Generator; import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.ni.Injector; @@ -27,7 +30,7 @@ import org.teavm.model.MethodReference; * * @author Alexey Andreev */ -public class ClassNativeGenerator implements Generator, Injector { +public class ClassNativeGenerator implements Generator, Injector, DependencyPlugin { @Override public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { @@ -35,6 +38,9 @@ public class ClassNativeGenerator implements Generator, Injector { case "getComponentType0": generateGetComponentType(context, writer); break; + case "getSuperclass": + generateGetSuperclass(context, writer); + break; } } @@ -44,6 +50,12 @@ public class ClassNativeGenerator implements Generator, Injector { writer.append("return item != null ? $rt_cls(item) : null;").softNewLine(); } + private void generateGetSuperclass(GeneratorContext context, SourceWriter writer) throws IOException { + String thisArg = context.getParameterName(0); + writer.append("var superclass = " + thisArg + ".$data.$meta.superclass;").softNewLine(); + writer.append("return superclass ? $rt_cls(superclass) : null;").softNewLine(); + } + @Override public void generate(InjectorContext context, MethodReference methodRef) throws IOException { switch (methodRef.getName()) { @@ -59,6 +71,9 @@ public class ClassNativeGenerator implements Generator, Injector { case "intClass": generateIntClass(context); break; + case "wrap": + context.writeExpr(context.getArgument(0)); + break; } } @@ -87,4 +102,17 @@ public class ClassNativeGenerator implements Generator, Injector { private void generateIntClass(InjectorContext context) throws IOException { context.getWriter().append("$rt_cls($rt_intcls())"); } + + @Override + public void methodAchieved(DependencyChecker checker, MethodDependency graph) { + switch (graph.getReference().getName()) { + case "booleanClass": + case "intClass": + case "wrap": + case "getSuperclass": + case "getComponentType0": + graph.getResult().propagate("java.lang.Class"); + break; + } + } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index c9c91049e..cbe325ca4 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -15,6 +15,7 @@ */ package org.teavm.classlib.java.lang; +import org.teavm.dependency.PluggableDependency; import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.ni.InjectedBy; @@ -22,7 +23,7 @@ import org.teavm.javascript.ni.InjectedBy; * * @author Alexey Andreev */ -public class TClass extends TObject { +public class TClass extends TObject { TString name; boolean primitive; boolean array; @@ -60,15 +61,26 @@ public class TClass extends TObject { } @GeneratedBy(ClassNativeGenerator.class) + @PluggableDependency(ClassNativeGenerator.class) private native TClass getComponentType0(); @InjectedBy(ClassNativeGenerator.class) + @PluggableDependency(ClassNativeGenerator.class) static native TClass booleanClass(); @InjectedBy(ClassNativeGenerator.class) + @PluggableDependency(ClassNativeGenerator.class) static native TClass intClass(); + @InjectedBy(ClassNativeGenerator.class) + @PluggableDependency(ClassNativeGenerator.class) + public static native TClass wrap(Class cls); + public boolean desiredAssertionStatus() { return true; } + + @GeneratedBy(ClassNativeGenerator.class) + @PluggableDependency(ClassNativeGenerator.class) + public native TClass getSuperclass(); } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneNotSupportedException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneNotSupportedException.java new file mode 100644 index 000000000..79631d0ff --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneNotSupportedException.java @@ -0,0 +1,32 @@ +/* + * Copyright 2014 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.lang; + +/** + * + * @author Alexey Andreev + */ +public class TCloneNotSupportedException extends TException { + private static final long serialVersionUID = 4908200987785128012L; + + public TCloneNotSupportedException() { + super(); + } + + public TCloneNotSupportedException(TString message) { + super(message); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneable.java new file mode 100644 index 000000000..649a82295 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneable.java @@ -0,0 +1,23 @@ +/* + * Copyright 2014 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.lang; + +/** + * + * @author Alexey Andreev + */ +public interface TCloneable { +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java new file mode 100644 index 000000000..52e02f196 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java @@ -0,0 +1,79 @@ +/* + * Copyright 2014 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.lang; + +import org.teavm.classlib.java.io.TSerializable; +import org.teavm.javascript.ni.Rename; + +/** + * + * @author Alexey Andreev + */ +public abstract class TEnum> extends TObject implements TComparable, TSerializable { + private TString name; + private int ordinal; + + protected TEnum(TString name, int ordinal) { + this.name = name; + this.ordinal = ordinal; + } + + public final TString name() { + return name; + } + + public final int ordinal() { + return ordinal; + } + + @Override + @Rename("toString") + public TString toString0() { + return name; + } + + @Override + public final boolean equals(TObject other) { + return this == other; + } + + @Override + public final int hashCode() { + return super.hashCode(); + } + + @Override + protected final TObject clone() throws TCloneNotSupportedException { + throw new TCloneNotSupportedException(); + } + + @SuppressWarnings("unchecked") + public final TClass getDeclaringClass() { + TClass thisClass = TClass.wrap(getClass()); + TClass superClass = thisClass.getSuperclass(); + return (TClass)(superClass == TClass.wrap(TEnum.class) ? thisClass : superClass); + } + + @Override + public final int compareTo(E o) { + if (o.getDeclaringClass() != getDeclaringClass()) { + throw new TIllegalArgumentException(TString.wrap("Can't compare " + + getDeclaringClass().getName().toString() + " to " + + o.getDeclaringClass().getName().toString())); + } + return TInteger.compare(ordinal, o.ordinal()); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java new file mode 100644 index 000000000..f7a346b86 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java @@ -0,0 +1,26 @@ +/* + * Copyright 2014 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.lang; + +import org.teavm.classlib.java.util.TIterator; + +/** + * + * @author Alexey Andreev + */ +public interface TIterable { + TIterator iterator(); +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java new file mode 100644 index 000000000..d1348a7fe --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java @@ -0,0 +1,52 @@ +/* + * Copyright 2014 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.lang; + +/** + * + * @author Alexey Andreev + */ +public class TLong extends TNumber { + private long value; + + public TLong(long value) { + this.value = value; + } + + public static TLong valueOf(long value) { + return new TLong(value); + } + + @Override + public int intValue() { + return (int)value; + } + + @Override + public long longValue() { + return value; + } + + @Override + public float floatValue() { + return value; + } + + @Override + public double doubleValue() { + return value; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index c44cfec52..a9cbc9a0f 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -59,7 +59,7 @@ public class TObject { @Override @GeneratedBy(ObjectNativeGenerator.class) @PluggableDependency(ObjectNativeGenerator.class) - protected native TObject clone(); + protected native TObject clone() throws TCloneNotSupportedException; @Rename("notify") public final void notify0() { 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 index 2a213f9b1..512e3e599 100644 --- 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 @@ -53,7 +53,7 @@ public class TStringBuilder extends TAbstractStringBuilder implements TAppendabl } @Override - protected TStringBuilder append(double value) { + public TStringBuilder append(double value) { super.append(value); return this; } 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 index 5a074a5a6..ce1b6d3ba 100644 --- 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 @@ -17,6 +17,8 @@ package org.teavm.classlib.java.util; import org.teavm.classlib.java.lang.TMath; import org.teavm.classlib.java.lang.TObject; +import org.teavm.classlib.java.lang.TString; +import org.teavm.classlib.java.lang.TStringBuilder; /** * @@ -40,4 +42,121 @@ public class TArrays extends TObject { } return result; } + + public static TString toString(TObject[] a) { + TStringBuilder sb = new TStringBuilder(); + sb.append(TString.wrap("[")); + for (int i = 0; i < a.length; ++i) { + if (i > 0) { + sb.append(TString.wrap(", ")); + } + sb.append(a[i]); + } + sb.append(TString.wrap("]")); + return TString.wrap(sb.toString()); + } + + public static TString toString(boolean[] a) { + TStringBuilder sb = new TStringBuilder(); + sb.append(TString.wrap("[")); + for (int i = 0; i < a.length; ++i) { + if (i > 0) { + sb.append(TString.wrap(", ")); + } + sb.append(a[i]); + } + sb.append(TString.wrap("]")); + return TString.wrap(sb.toString()); + } + + public static TString toString(byte[] a) { + TStringBuilder sb = new TStringBuilder(); + sb.append(TString.wrap("[")); + for (int i = 0; i < a.length; ++i) { + if (i > 0) { + sb.append(TString.wrap(", ")); + } + sb.append(a[i]); + } + sb.append(TString.wrap("]")); + return TString.wrap(sb.toString()); + } + + public static TString toString(short[] a) { + TStringBuilder sb = new TStringBuilder(); + sb.append(TString.wrap("[")); + for (int i = 0; i < a.length; ++i) { + if (i > 0) { + sb.append(TString.wrap(", ")); + } + sb.append(a[i]); + } + sb.append(TString.wrap("]")); + return TString.wrap(sb.toString()); + } + + public static TString toString(char[] a) { + TStringBuilder sb = new TStringBuilder(); + sb.append(TString.wrap("[")); + for (int i = 0; i < a.length; ++i) { + if (i > 0) { + sb.append(TString.wrap(", ")); + } + sb.append(a[i]); + } + sb.append(TString.wrap("]")); + return TString.wrap(sb.toString()); + } + + public static TString toString(int[] a) { + TStringBuilder sb = new TStringBuilder(); + sb.append(TString.wrap("[")); + for (int i = 0; i < a.length; ++i) { + if (i > 0) { + sb.append(TString.wrap(", ")); + } + sb.append(a[i]); + } + sb.append(TString.wrap("]")); + return TString.wrap(sb.toString()); + } + + public static TString toString(long[] a) { + TStringBuilder sb = new TStringBuilder(); + sb.append(TString.wrap("[")); + for (int i = 0; i < a.length; ++i) { + if (i > 0) { + sb.append(TString.wrap(", ")); + } + sb.append(a[i]); + } + sb.append(TString.wrap("]")); + return TString.wrap(sb.toString()); + } + + public static TString toString(float[] a) { + TStringBuilder sb = new TStringBuilder(); + sb.append(TString.wrap("[")); + for (int i = 0; i < a.length; ++i) { + if (i > 0) { + sb.append(TString.wrap(", ")); + } + sb.append(a[i]); + } + sb.append(TString.wrap("]")); + return TString.wrap(sb.toString()); + } + + public static TString toString(double[] a) { + TStringBuilder sb = new TStringBuilder(); + sb.append(TString.wrap("[")); + for (int i = 0; i < a.length; ++i) { + if (i > 0) { + sb.append(TString.wrap(", ")); + } + sb.append(a[i]); + } + sb.append(TString.wrap("]")); + return TString.wrap(sb.toString()); + } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java new file mode 100644 index 000000000..0cadc2e8b --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 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 org.teavm.classlib.java.lang.TObject; + +/** + * + * @author Alexey Andreev + */ +public interface TIterator { + boolean hasNext(); + + E next(); + + void remove(); +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java new file mode 100644 index 000000000..c3f0615ae --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java @@ -0,0 +1,27 @@ +/* + * Copyright 2014 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.concurrent; + +import org.teavm.classlib.java.lang.TException; +import org.teavm.classlib.java.lang.TObject; + +/** + * + * @author Alexey Andreev + */ +public interface TCallable { + V call() throws TException; +} diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/ClassTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/ClassTest.java index 2896d5142..852568c79 100644 --- a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/ClassTest.java +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/ClassTest.java @@ -33,6 +33,26 @@ public class ClassTest { assertEquals("java.lang.Object", new Object().getClass().getName()); } + @Test + public void superClassFound() { + assertEquals(Number.class, Integer.class.getSuperclass()); + } + + @Test + public void superClassOfObjectIsNull() { + assertNull(Object.class.getSuperclass()); + } + + @Test + public void superClassOfArrayIsObject() { + assertEquals(Object.class, Runnable[].class.getSuperclass()); + } + + @Test + public void superClassOfPrimitiveIsNull() { + assertNull(int.class.getSuperclass()); + } + @Test public void objectClassConsideredNotArray() { assertFalse(Object.class.isArray()); diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index 0db105659..101e6d7dd 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -189,6 +189,10 @@ public class Renderer implements ExprVisitor, StatementVisitor { writer.appendClass(iface); } writer.append("]"); + if (cls.getParentName() != null) { + writer.append(",").ws(); + writer.append("superclass").ws().append(":").ws().appendClass(cls.getParentName()); + } writer.ws().append("};").softNewLine(); if (!cls.getModifiers().contains(NodeModifier.INTERFACE)) { writer.appendClass(cls.getName()).append("_$clinit").ws().append("=").ws().append("function()").ws() diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index 02f6e9043..3a1a07e5d 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -108,7 +108,7 @@ $rt_arraycls = function(cls) { }; arraycls.prototype = new ($rt_objcls())(); arraycls.prototype.constructor = arraycls; - arraycls.$meta = { item : cls, supertypes : [$rt_objcls()], primitive : false }; + arraycls.$meta = { item : cls, supertypes : [$rt_objcls()], primitive : false, superclass : $rt_objcls() }; cls.$array = arraycls; } return cls.$array; diff --git a/teavm-html4j/pom.xml b/teavm-html4j/pom.xml index 064790534..6bd1e7bd0 100644 --- a/teavm-html4j/pom.xml +++ b/teavm-html4j/pom.xml @@ -84,9 +84,9 @@ true ${project.build.directory}/javascript-tck org.teavm.html4j.testing.KOTestAdapter - +