diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/ClassGenerator.java b/classlib/src/main/java/org/teavm/classlib/java/lang/ClassGenerator.java index 4631029d4..847827d71 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/ClassGenerator.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/ClassGenerator.java @@ -89,6 +89,10 @@ public class ClassGenerator implements Generator, Injector, DependencyPlugin { Set accessibleFields = reflection.getAccessibleFields(className); ClassReader cls = context.getClassSource().get(className); + if (cls == null) { + return; + } + writer.appendClass(className).append(".$meta.fields").ws().append('=').ws().append('[').indent(); generateCreateMembers(writer, cls.getFields(), field -> { @@ -120,6 +124,10 @@ public class ClassGenerator implements Generator, Injector, DependencyPlugin { Set accessibleMethods = reflection.getAccessibleMethods(className); ClassReader cls = context.getClassSource().get(className); + if (cls == null) { + return; + } + writer.appendClass(className).append(".$meta.methods").ws().append('=').ws().append('[').indent(); generateCreateMembers(writer, cls.getMethods(), method -> { @@ -160,7 +168,8 @@ public class ClassGenerator implements Generator, Injector, DependencyPlugin { appendProperty(writer, "name", true, () -> writer.append('"') .append(RenderingUtil.escapeString(member.getName())).append('"')); - appendProperty(writer, "modifiers", false, () -> writer.append(packModifiers(member.readModifiers()))); + appendProperty(writer, "modifiers", false, () -> writer.append( + ElementModifier.pack(member.readModifiers()))); appendProperty(writer, "accessLevel", false, () -> writer.append(member.getLevel().ordinal())); renderer.render(member); writer.outdent().softNewLine().append("}"); @@ -323,18 +332,4 @@ public class ClassGenerator implements Generator, Injector, DependencyPlugin { private interface MemberRenderer { void render(T member) throws IOException; } - - private int packModifiers(Set elementModifiers) { - ElementModifier[] knownModifiers = ElementModifier.values(); - int value = 0; - int bit = 1; - for (int i = 0; i < knownModifiers.length; ++i) { - ElementModifier modifier = knownModifiers[i]; - if (elementModifiers.contains(modifier)) { - value |= bit; - } - bit <<= 1; - } - return value; - } } diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index c56e30321..0a133b31a 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -325,6 +325,12 @@ public class TClass extends TObject implements TAnnotatedElement { } } + public int getModifiers() { + int flags = platformClass.getMetadata().getFlags(); + int accessLevel = platformClass.getMetadata().getAccessLevel(); + return Flags.getModifiers(flags, accessLevel); + } + public boolean desiredAssertionStatus() { return true; } diff --git a/core/src/main/java/org/teavm/ast/ClassNode.java b/core/src/main/java/org/teavm/ast/ClassNode.java index 3bc4048e9..642f10a4e 100644 --- a/core/src/main/java/org/teavm/ast/ClassNode.java +++ b/core/src/main/java/org/teavm/ast/ClassNode.java @@ -19,12 +19,14 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Set; +import org.teavm.model.AccessLevel; import org.teavm.model.ElementModifier; public class ClassNode { private String name; private String parentName; private Set modifiers = EnumSet.noneOf(ElementModifier.class); + private AccessLevel accessLevel = AccessLevel.PUBLIC; private List fields = new ArrayList<>(); private List methods = new ArrayList<>(); private List interfaces = new ArrayList<>(); @@ -57,4 +59,12 @@ public class ClassNode { public Set getModifiers() { return modifiers; } + + public AccessLevel getAccessLevel() { + return accessLevel; + } + + public void setAccessLevel(AccessLevel accessLevel) { + this.accessLevel = accessLevel; + } } diff --git a/core/src/main/java/org/teavm/ast/decompilation/Decompiler.java b/core/src/main/java/org/teavm/ast/decompilation/Decompiler.java index acae70ed9..1c04baa8c 100644 --- a/core/src/main/java/org/teavm/ast/decompilation/Decompiler.java +++ b/core/src/main/java/org/teavm/ast/decompilation/Decompiler.java @@ -209,6 +209,7 @@ public class Decompiler { } clsNode.getInterfaces().addAll(cls.getInterfaces()); clsNode.getModifiers().addAll(cls.getModifiers()); + clsNode.setAccessLevel(cls.getLevel()); return clsNode; } diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java index 632711a80..0988d622d 100644 --- a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java +++ b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java @@ -467,11 +467,10 @@ public class Renderer implements RenderingManager { writer.appendClass(iface); } writer.append("],").ws(); - int flags = 0; - if (cls.getModifiers().contains(ElementModifier.ENUM)) { - flags |= 1; - } - writer.append(flags).append(',').ws(); + + writer.append(ElementModifier.pack(cls.getModifiers())).append(',').ws(); + writer.append(cls.getAccessLevel().ordinal()).append(',').ws(); + MethodReader clinit = classSource.get(cls.getName()).getMethod( new MethodDescriptor("", ValueType.VOID)); if (clinit != null) { diff --git a/core/src/main/java/org/teavm/cache/AstIO.java b/core/src/main/java/org/teavm/cache/AstIO.java index ec64750e2..54f6d58ed 100644 --- a/core/src/main/java/org/teavm/cache/AstIO.java +++ b/core/src/main/java/org/teavm/cache/AstIO.java @@ -92,7 +92,7 @@ public class AstIO { } public void write(DataOutput output, RegularMethodNode method) throws IOException { - output.writeInt(packModifiers(method.getModifiers())); + output.writeInt(ElementModifier.pack(method.getModifiers())); output.writeShort(method.getVariables().size()); for (VariableNode var : method.getVariables()) { write(output, var); @@ -136,7 +136,7 @@ public class AstIO { } public void writeAsync(DataOutput output, AsyncMethodNode method) throws IOException { - output.writeInt(packModifiers(method.getModifiers())); + output.writeInt(ElementModifier.pack(method.getModifiers())); output.writeShort(method.getVariables().size()); for (VariableNode var : method.getVariables()) { write(output, var); @@ -167,14 +167,6 @@ public class AstIO { return node; } - private int packModifiers(Set modifiers) { - int packed = 0; - for (ElementModifier modifier : modifiers) { - packed |= 1 << modifier.ordinal(); - } - return packed; - } - private Set unpackModifiers(int packed) { EnumSet modifiers = EnumSet.noneOf(ElementModifier.class); while (packed != 0) { diff --git a/core/src/main/java/org/teavm/model/ElementModifier.java b/core/src/main/java/org/teavm/model/ElementModifier.java index 5669a7143..341975532 100644 --- a/core/src/main/java/org/teavm/model/ElementModifier.java +++ b/core/src/main/java/org/teavm/model/ElementModifier.java @@ -15,6 +15,8 @@ */ package org.teavm.model; +import java.util.Set; + /** * Represents flags for classes and class members. * @see ElementHolder @@ -37,5 +39,19 @@ public enum ElementModifier { SYNTHETIC, TRANSIENT, VARARGS, - VOLATILE + VOLATILE; + + public static int pack(Set elementModifiers) { + ElementModifier[] knownModifiers = ElementModifier.values(); + int value = 0; + int bit = 1; + for (int i = 0; i < knownModifiers.length; ++i) { + ElementModifier modifier = knownModifiers[i]; + if (elementModifiers.contains(modifier)) { + value |= bit; + } + bit <<= 1; + } + return value; + } } diff --git a/core/src/main/resources/org/teavm/backend/javascript/runtime.js b/core/src/main/resources/org/teavm/backend/javascript/runtime.js index 470db3011..9c1c2e615 100644 --- a/core/src/main/resources/org/teavm/backend/javascript/runtime.js +++ b/core/src/main/resources/org/teavm/backend/javascript/runtime.js @@ -418,7 +418,7 @@ function $rt_putStderr(ch) { } } function $rt_metadata(data) { - for (var i = 0; i < data.length; i += 7) { + for (var i = 0; i < data.length; i += 8) { var cls = data[i]; cls.$meta = {}; var m = cls.$meta; @@ -434,15 +434,19 @@ function $rt_metadata(data) { cls.prototype = {}; } var flags = data[i + 4]; - m.enum = (flags & 1) != 0; + m.enum = (flags & 16) != 0; + m.flags = flags; m.primitive = false; m.item = null; cls.prototype.constructor = cls; cls.classObject = null; - var clinit = data[i + 5]; + + m.accessLevel = data[i + 5]; + + var clinit = data[i + 6]; cls.$clinit = clinit !== 0 ? clinit : function() {}; - var virtualMethods = data[i + 6]; + var virtualMethods = data[i + 7]; for (var j = 0; j < virtualMethods.length; j += 2) { var name = virtualMethods[j]; var func = virtualMethods[j + 1]; diff --git a/platform/src/main/java/org/teavm/platform/PlatformClassMetadata.java b/platform/src/main/java/org/teavm/platform/PlatformClassMetadata.java index 247328d39..bbca2938d 100644 --- a/platform/src/main/java/org/teavm/platform/PlatformClassMetadata.java +++ b/platform/src/main/java/org/teavm/platform/PlatformClassMetadata.java @@ -39,4 +39,7 @@ public interface PlatformClassMetadata extends JSObject { @JSProperty int getFlags(); + + @JSProperty + int getAccessLevel(); } diff --git a/samples/kotlin/teavm-samples-kotlin.iml b/samples/kotlin/teavm-samples-kotlin.iml index d6d03f110..1690c4c0e 100644 --- a/samples/kotlin/teavm-samples-kotlin.iml +++ b/samples/kotlin/teavm-samples-kotlin.iml @@ -10,6 +10,10 @@ + + + +