Adds complete enum support

This commit is contained in:
konsoletyper 2014-02-20 11:58:44 +04:00
parent f3ae632786
commit f63d0cd8d0
21 changed files with 419 additions and 186 deletions

View File

@ -0,0 +1,68 @@
/*
* 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.impl;
import org.teavm.dependency.*;
import org.teavm.model.ClassReader;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReader;
import org.teavm.model.ValueType;
/**
*
* @author Alexey Andreev
*/
public class EnumDependencySupport implements DependencyListener {
private DependencyNode allEnums;
private volatile DependencyStack enumConstantsStack;
@Override
public void started(DependencyChecker dependencyChecker) {
allEnums = dependencyChecker.createNode();
}
@Override
public void classAchieved(DependencyChecker dependencyChecker, String className) {
ClassReader cls = dependencyChecker.getClassSource().get(className);
if (cls == null || cls.getParent() == null || !cls.getParent().equals("java.lang.Enum")) {
allEnums.propagate(className);
}
if (enumConstantsStack != null) {
MethodReader method = cls.getMethod(new MethodDescriptor("values",
ValueType.arrayOf(ValueType.object(cls.getName()))));
if (method != null) {
dependencyChecker.linkMethod(method.getReference(), enumConstantsStack).use();
}
}
}
@Override
public void methodAchieved(DependencyChecker dependencyChecker, MethodDependency method) {
if (method.getReference().getClassName().equals("java.lang.Class") &&
method.getReference().getName().equals("getEnumConstantsImpl")) {
allEnums.connect(method.getResult().getArrayItem());
method.getResult().propagate("[java.lang.Enum");
enumConstantsStack = method.getStack();
for (String cls : dependencyChecker.getAchievableClasses()) {
classAchieved(dependencyChecker, cls);
}
}
}
@Override
public void fieldAchieved(DependencyChecker dependencyChecker, FieldDependency field) {
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.impl;
import org.teavm.javascript.ni.PreserveOriginalName;
import org.teavm.model.*;
/**
*
* @author Alexey Andreev
*/
public class EnumTransformer implements ClassHolderTransformer {
@Override
public void transformClass(ClassHolder cls, ClassReaderSource innerSource) {
if (cls.getParent() != null && !cls.getParent().equals("java.lang.Enum")) {
return;
}
MethodHolder method = cls.getMethod(new MethodDescriptor("values",
ValueType.arrayOf(ValueType.object(cls.getName()))));
if (method == null) {
return;
}
method.getAnnotations().add(new AnnotationHolder(PreserveOriginalName.class.getName()));
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.impl;
import org.teavm.javascript.JavascriptBuilderHost;
import org.teavm.javascript.JavascriptBuilderPlugin;
/**
*
* @author Alexey Andreev
*/
public class JCLPlugin implements JavascriptBuilderPlugin {
@Override
public void install(JavascriptBuilderHost host) {
host.add(new EnumDependencySupport());
host.add(new EnumTransformer());
}
}

View File

@ -74,6 +74,10 @@ public class ClassNativeGenerator implements Generator, Injector, DependencyPlug
case "wrap":
context.writeExpr(context.getArgument(0));
break;
case "getEnumConstantsImpl":
context.writeExpr(context.getArgument(0));
context.getWriter().append(".$data.values()");
break;
}
}

View File

@ -100,11 +100,12 @@ public class ObjectNativeGenerator implements Generator, Injector, DependencyPlu
}
private void generateClone(GeneratorContext context, SourceWriter writer) throws IOException {
writer.append("var copy = new ").append(context.getParameterName(0)).append(".constructor();").softNewLine();
writer.append("for (var field in obj) {").softNewLine().indent();
writer.append("if (!obj.hasOwnProperty(field)) {").softNewLine().indent();
String obj = context.getParameterName(0);
writer.append("var copy = new ").append(obj).append(".constructor();").softNewLine();
writer.append("for (var field in " + obj + ") {").softNewLine().indent();
writer.append("if (!" + obj + ".hasOwnProperty(field)) {").softNewLine().indent();
writer.append("continue;").softNewLine().outdent().append("}").softNewLine();
writer.append("copy[field] = obj[field];").softNewLine().outdent().append("}").softNewLine();
writer.append("copy[field] = " + obj + "[field];").softNewLine().outdent().append("}").softNewLine();
writer.append("return copy;").softNewLine();
}

View File

@ -18,6 +18,7 @@ package org.teavm.classlib.java.lang;
import org.teavm.classlib.impl.unicode.UnicodeHelper;
import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.GeneratedBy;
import org.teavm.javascript.ni.Rename;
/**
*
@ -41,6 +42,20 @@ public class TCharacter extends TObject {
return new TCharacter(value);
}
@Override
@Rename("toString")
public TString toString0() {
return new TString(new char[] { value });
}
@Override
public boolean equals(TObject other) {
if (this == other) {
return true;
}
return other instanceof TCharacter && ((TCharacter)other).value == value;
}
@GeneratedBy(CharacterNativeGenerator.class)
public static native char toLowerCase(char ch);

View File

@ -27,6 +27,7 @@ public class TClass<T extends TObject> extends TObject {
TString name;
boolean primitive;
boolean array;
boolean isEnum;
private TClass<?> componentType;
private boolean componentTypeDirty = true;
@ -52,6 +53,10 @@ public class TClass<T extends TObject> extends TObject {
return array;
}
public boolean isEnum() {
return isEnum;
}
public TClass<?> getComponentType() {
if (componentTypeDirty) {
componentType = getComponentType0();
@ -83,4 +88,11 @@ public class TClass<T extends TObject> extends TObject {
@GeneratedBy(ClassNativeGenerator.class)
@PluggableDependency(ClassNativeGenerator.class)
public native TClass<? super T> getSuperclass();
public T[] getEnumConstants() {
return isEnum ? getEnumConstantsImpl() : null;
}
@InjectedBy(ClassNativeGenerator.class)
public native T[] getEnumConstantsImpl();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013 Alexey Andreev.
* 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.
@ -13,18 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.org.junit;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
package org.teavm.classlib.java.lang;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
* @author Alexey Andreev
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {
public class TClassCastException extends TRuntimeException {
private static final long serialVersionUID = 5744987817019231273L;
public TClassCastException() {
super();
}
public TClassCastException(TString message) {
super(message);
}
}

View File

@ -16,6 +16,7 @@
package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.GeneratedBy;
import org.teavm.javascript.ni.Rename;
/**
*
@ -52,6 +53,20 @@ public class TDouble extends TNumber {
return new TDouble(d);
}
@Override
@Rename("toString")
public TString toString0() {
return TString.wrap(new TStringBuilder().append(value).toString());
}
@Override
public boolean equals(TObject other) {
if (this == other) {
return true;
}
return other instanceof TDouble && ((TDouble)other).value == value;
}
@GeneratedBy(DoubleNativeGenerator.class)
public static native boolean isNaN(double v);

View File

@ -62,9 +62,7 @@ public abstract class TEnum<E extends TEnum<E>> extends TObject implements TComp
@SuppressWarnings("unchecked")
public final TClass<E> getDeclaringClass() {
TClass<?> thisClass = TClass.wrap(getClass());
TClass<?> superClass = thisClass.getSuperclass();
return (TClass<E>)(superClass == TClass.wrap(TEnum.class) ? thisClass : superClass);
return (TClass<E>)TClass.wrap(getClass());
}
@Override
@ -76,4 +74,19 @@ public abstract class TEnum<E extends TEnum<E>> extends TObject implements TComp
}
return TInteger.compare(ordinal, o.ordinal());
}
public static <T extends TEnum<T>> T valueOf(TClass<T> enumType, TString name) {
// TODO: speed-up this method, use caching
T[] constants = enumType.getEnumConstants();
if (constants == null) {
throw new TIllegalArgumentException(TString.wrap("Class does not represent enum: " + enumType.getName()));
}
for (T constant : constants) {
if (constant.name().equals(name)) {
return constant;
}
}
throw new TIllegalArgumentException(TString.wrap("Enum " + enumType.getName() + " does not have the " + name +
"constant"));
}
}

View File

@ -15,6 +15,8 @@
*/
package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.Rename;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
@ -49,4 +51,18 @@ public class TLong extends TNumber {
public double doubleValue() {
return value;
}
@Override
@Rename("toString")
public TString toString0() {
return TString.wrap(new TStringBuilder().append(value).toString());
}
@Override
public boolean equals(TObject other) {
if (this == other) {
return true;
}
return other instanceof TLong && ((TLong)other).value == value;
}
}

View File

@ -1,87 +0,0 @@
/*
* Copyright 2013 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.org.junit;
import org.teavm.javascript.ni.GeneratedBy;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class Assert {
public static void assertTrue(boolean condition) {
if (!condition) {
fail();
}
}
public static void assertFalse(boolean condition) {
if (condition) {
fail();
}
}
@GeneratedBy(AssertNativeGenerator.class)
public static native void fail();
public static void assertEquals(Object expected, Object actual) {
if (expected != null ? !expected.equals(actual) : actual != null) {
fail();
}
}
public static void assertNotEquals(Object expected, Object actual) {
if (expected != null ? expected.equals(actual) : actual == null) {
fail();
}
}
public static void assertEquals(long expected, long actual) {
if (expected != actual) {
fail();
}
}
public static void assertNotEquals(long expected, long actual) {
if (expected == actual) {
fail();
}
}
public static void assertNotNull(Object object) {
if (object == null) {
fail();
}
}
public static void assertNull(Object object) {
if (object != null) {
fail();
}
}
public static void assertSame(Object expected, Object actual) {
if (expected != actual) {
fail();
}
}
public static void assertNotSame(Object expected, Object actual) {
if (expected == actual) {
fail();
}
}
}

View File

@ -1,42 +0,0 @@
/*
* Copyright 2013 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.org.junit;
import java.io.IOException;
import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class AssertNativeGenerator implements Generator {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef)
throws IOException {
switch (methodRef.getDescriptor().getName()) {
case "fail":
generateFail(writer);
break;
}
}
private void generateFail(SourceWriter writer) throws IOException {
writer.append("throw new Error();").newLine();
}
}

View File

@ -0,0 +1 @@
org.teavm.classlib.impl.JCLPlugin

View File

@ -13,4 +13,3 @@
# limitations under the License.
packagePrefix.java=org.teavm.classlib
classPrefix.java=T
packagePrefix.org.junit=org.teavm.classlib

View File

@ -0,0 +1,73 @@
/*
* 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 static org.junit.Assert.*;
import org.junit.Test;
/**
*
* @author Alexey Andreev
*/
public class EnumTest {
private static enum Foo {
A, B, C
}
private static enum Bar {
D, E
}
@Test
public void sameConstantsAreEqual() {
assertEquals(Foo.A, Foo.A);
}
@Test
public void differentConstansAreNotEqual() {
assertNotEquals(Foo.A, Foo.B);
}
@Test
public void constantsOfDifferentEnumsAreNotEqual() {
assertNotEquals(Foo.A, Bar.D);
}
@Test
public void declaringClassComputed() {
assertEquals(Foo.class, Foo.A.getDeclaringClass());
}
@Test
public void comparisonGivesZeroForSameConstants() {
assertEquals(0, Foo.A.compareTo(Foo.A));
}
@Test
public void comparisonGivesPositiveForLaterConstant() {
assertTrue(Foo.B.compareTo(Foo.A) > 0);
}
@Test
public void comparisonGivesNegativeForEarlierConstant() {
assertTrue(Foo.A.compareTo(Foo.B) < 0);
}
@Test
public void valueOfReturnsConstant() {
assertEquals("A", Enum.valueOf(Foo.class, "A").name());
}
}

View File

@ -231,9 +231,13 @@ public class Decompiler {
Set<NodeModifier> result = EnumSet.noneOf(NodeModifier.class);
if (modifiers.contains(ElementModifier.STATIC)) {
result.add(NodeModifier.STATIC);
} else if (modifiers.contains(ElementModifier.INTERFACE)) {
}
if (modifiers.contains(ElementModifier.INTERFACE)) {
result.add(NodeModifier.INTERFACE);
}
if (modifiers.contains(ElementModifier.ENUM)) {
result.add(NodeModifier.ENUM);
}
return result;
}

View File

@ -135,6 +135,11 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
ValueType.object("java.lang.Class"))), DependencyStack.ROOT).use();
dependencyChecker.linkMethod(new MethodReference("java.lang.String", new MethodDescriptor("<init>",
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID)), DependencyStack.ROOT).use();
dependencyChecker.linkMethod(new MethodReference("java.lang.String", new MethodDescriptor("getChars",
ValueType.INTEGER, ValueType.INTEGER, ValueType.arrayOf(ValueType.CHARACTER), ValueType.INTEGER,
ValueType.VOID)), DependencyStack.ROOT).use();
dependencyChecker.linkMethod(new MethodReference("java.lang.Object", new MethodDescriptor("clone",
ValueType.object("java.lang.Object"))), DependencyStack.ROOT).use();
executor.complete();
if (hasMissingItems()) {
return;

View File

@ -77,6 +77,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
try {
renderRuntimeCls();
renderRuntimeString();
renderRuntimeUnwrapString();
renderRuntimeObjcls();
} catch (NamingException e) {
throw new RenderingException("Error rendering runtime methods. See a cause for details", e);
@ -110,6 +111,11 @@ public class Renderer implements ExprVisitor, StatementVisitor {
.append("=").ws().append("clsProto.$meta.item").ws().append("?").ws()
.append("1").ws().append(":").ws().append("0;").softNewLine();
}
if (classSource.get(classClass).getField("isEnum") != null) {
writer.append("cls.").appendField(new FieldReference(classClass, "isEnum")).ws()
.append("=").ws().append("clsProto.$meta.enum").ws().append("?").ws()
.append("1").ws().append(":").ws().append("0;").softNewLine();
}
writer.append("clsProto.classObject").ws().append("=").ws().append("cls;").softNewLine();
writer.outdent().append("}").softNewLine();
writer.append("return cls;").softNewLine();
@ -131,6 +137,25 @@ public class Renderer implements ExprVisitor, StatementVisitor {
writer.outdent().append("}").newLine();
}
private void renderRuntimeUnwrapString() throws IOException {
String stringClass = "java.lang.String";
MethodReference stringLen = new MethodReference(stringClass, new MethodDescriptor(
"length", ValueType.INTEGER));
MethodReference getChars = new MethodReference(stringClass, new MethodDescriptor(
"getChars", ValueType.INTEGER, ValueType.INTEGER, ValueType.arrayOf(ValueType.CHARACTER),
ValueType.INTEGER, ValueType.VOID));
writer.append("$rt_ustr = function(str) {").indent().softNewLine();
writer.append("var result = \"\";").softNewLine();
writer.append("var sz = ").appendMethodBody(stringLen).append("(str);").softNewLine();
writer.append("var array = $rt_createCharArray(sz);");
writer.appendMethodBody(getChars).append("(str, 0, sz, array, 0);");
writer.append("for (var i = 0; i < sz; i = (i + 1) | 0) {").indent().softNewLine();
writer.append("result += String.fromCharCode(array.data[i]);").softNewLine();
writer.outdent().append("}").softNewLine();
writer.append("return result;").softNewLine();
writer.outdent().append("}").newLine();
}
private void renderRuntimeObjcls() throws IOException {
writer.append("$rt_objcls = function() { return ").appendClass("java.lang.Object").append("; }").newLine();
}
@ -174,7 +199,9 @@ public class Renderer implements ExprVisitor, StatementVisitor {
}
writer.appendClass(cls.getName()).append(".$meta").ws().append("=").ws().append("{").ws();
writer.append("name").ws().append(":").ws().append("\"").append(cls.getName()).append("\",").ws();
writer.append("primitive").ws().append(":").ws().append("false,").ws();
if (cls.getModifiers().contains(NodeModifier.ENUM)) {
writer.append("enum").ws().append(":").ws().append("true,").ws();
}
writer.append("supertypes").ws().append(":").ws().append("[");
boolean first = true;
if (cls.getParentName() != null) {
@ -195,7 +222,10 @@ public class Renderer implements ExprVisitor, StatementVisitor {
}
writer.ws().append("};").softNewLine();
if (!cls.getModifiers().contains(NodeModifier.INTERFACE)) {
writer.appendClass(cls.getName()).append("_$clinit").ws().append("=").ws().append("function()").ws()
writer.appendClass(cls.getName()).append(".$clinit").ws().append("=").ws()
.append("function()").ws().append("{").ws()
.appendClass(cls.getName()).append("_$clinit();").ws().append("}").newLine();
writer.append("function ").appendClass(cls.getName()).append("_$clinit()").ws()
.append("{").softNewLine().indent();
writer.appendClass(cls.getName()).append("_$clinit").ws().append("=").ws()
.append("function(){};").newLine();
@ -213,7 +243,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
writer.outdent().append("}").newLine();
for (MethodNode method : cls.getMethods()) {
cls.getMethods();
if (!method.getModifiers().contains(NodeModifier.STATIC)) {
if (!method.getModifiers().contains(NodeModifier.STATIC) || method.isOriginalNamePreserved()) {
renderDeclaration(method);
}
}
@ -287,6 +317,18 @@ public class Renderer implements ExprVisitor, StatementVisitor {
public void renderDeclaration(MethodNode method) throws RenderingException, IOException {
try {
if (method.getModifiers().contains(NodeModifier.STATIC)) {
renderStaticDeclaration(method);
} else {
renderVirtualDeclaration(method);
}
} catch (NamingException e) {
throw new RenderingException("Error rendering method " + method.getReference() + ". " +
"See cause for details", e);
}
}
private void renderVirtualDeclaration(MethodNode method) throws NamingException, IOException {
MethodReference ref = method.getReference();
if (ref.getDescriptor().getName().equals("<init>")) {
renderInitializer(method);
@ -312,9 +354,30 @@ public class Renderer implements ExprVisitor, StatementVisitor {
.ws().appendClass(ref.getClassName()).append(".prototype.").appendMethod(ref)
.append(';').newLine();
}
} catch (NamingException e) {
throw new RenderingException("Error rendering method " + method.getReference() + ". " +
"See cause for details", e);
}
private void renderStaticDeclaration(MethodNode method) throws NamingException, IOException {
MethodReference ref = method.getReference();
if (ref.getDescriptor().getName().equals("<init>")) {
renderInitializer(method);
}
writer.appendClass(ref.getClassName()).append(".").appendMethod(ref).ws().append("=").ws().append("function(");
for (int i = 0; i < ref.parameterCount(); ++i) {
if (i > 0) {
writer.append(", ");
}
writer.append(variableName(i + 1));
}
writer.append(")").ws().append("{").softNewLine().indent();
writer.append("return ").appendMethodBody(ref).append("(");
for (int i = 0; i < ref.parameterCount(); ++i) {
writer.append(",").ws().append(variableName(i + 1));
}
writer.append(");").softNewLine();
writer.outdent().append("}").newLine();
if (method.isOriginalNamePreserved()) {
writer.appendClass(ref.getClassName()).append(".").append(ref.getName()).ws().append("=")
.ws().appendClass(ref.getClassName()).append(".").appendMethod(ref).append(';').newLine();
}
}
@ -1190,12 +1253,13 @@ public class Renderer implements ExprVisitor, StatementVisitor {
InjectorHolder holder = injectorMap.get(ref);
if (holder == null) {
MethodHolder method = classSource.get(ref.getClassName()).getMethod(ref.getDescriptor());
holder = new InjectorHolder(null);
if (method != null) {
AnnotationHolder injectedByAnnot = method.getAnnotations().get(InjectedBy.class.getName());
if (injectedByAnnot != null) {
ValueType type = injectedByAnnot.getValues().get("value").getJavaClass();
holder = new InjectorHolder(instantiateInjector(((ValueType.Object)type).getClassName()));
} else {
holder = new InjectorHolder(null);
}
}
injectorMap.put(ref, holder);
}

View File

@ -21,5 +21,6 @@ package org.teavm.javascript.ast;
*/
public enum NodeModifier {
STATIC,
INTERFACE
INTERFACE,
ENUM
}

View File

@ -84,9 +84,9 @@
<scanDependencies>true</scanDependencies>
<outputDir>${project.build.directory}/javascript-tck</outputDir>
<adapterClass>org.teavm.html4j.testing.KOTestAdapter</adapterClass>
<!-- <wildcards>
<wildcards>
<param>net.java.html.js.tests.*Test</param>
</wildcards> -->
</wildcards>
</configuration>
</execution>
</executions>