mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Repair Class.getEnumConstants()
This commit is contained in:
parent
eba560d373
commit
a9ff14b599
|
@ -403,7 +403,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
writer.append("],").ws();
|
writer.append("],").ws();
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if (cls.getModifiers().contains(NodeModifier.ENUM)) {
|
if (cls.getModifiers().contains(NodeModifier.ENUM)) {
|
||||||
flags &= 1;
|
flags |= 1;
|
||||||
}
|
}
|
||||||
writer.append(flags).append(',').ws();
|
writer.append(flags).append(',').ws();
|
||||||
MethodHolder clinit = classSource.get(cls.getName()).getMethod(
|
MethodHolder clinit = classSource.get(cls.getName()).getMethod(
|
||||||
|
|
|
@ -328,23 +328,6 @@ function $rt_assertNotNaN(value) {
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
function $rt_methodStubs(data) {
|
|
||||||
for (var i = 0; i < data.length; i += 2) {
|
|
||||||
var clinit = data[i + 0];
|
|
||||||
var names = data[i + 1];
|
|
||||||
if (!(names instanceof Array)) {
|
|
||||||
names = [names];
|
|
||||||
}
|
|
||||||
for (var j = 0; j < names.length; j = (j + 1) | 0) {
|
|
||||||
window[names[j]] = (function(name, clinit) {
|
|
||||||
return function() {
|
|
||||||
clinit();
|
|
||||||
return window[name].apply(window, arguments);
|
|
||||||
}
|
|
||||||
})(names[j], clinit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var $rt_stdoutBuffer = "";
|
var $rt_stdoutBuffer = "";
|
||||||
function $rt_putStdout(ch) {
|
function $rt_putStdout(ch) {
|
||||||
if (ch == 0xA) {
|
if (ch == 0xA) {
|
||||||
|
@ -420,35 +403,6 @@ function $rt_metadata(data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function $rt_virtualMethods(cls) {
|
|
||||||
for (var i = 1; i < arguments.length; i += 2) {
|
|
||||||
var name = arguments[i];
|
|
||||||
var func = arguments[i + 1];
|
|
||||||
if (typeof name === 'string') {
|
|
||||||
cls.prototype[name] = func;
|
|
||||||
} else {
|
|
||||||
for (var j = 0; j < name.length; ++j) {
|
|
||||||
cls.prototype[name[j]] = func;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function $rt_virtualMethods(data) {
|
|
||||||
for (var i = 0; i < data.length; i += 2) {
|
|
||||||
var cls = data[i + 0];
|
|
||||||
var methods = data[i + 1];
|
|
||||||
for (var j = 0; j < methods.length; j += 2) {
|
|
||||||
var name = methods[j + 0];
|
|
||||||
var func = methods[j + 1];
|
|
||||||
if (typeof name === 'string') {
|
|
||||||
name = [name];
|
|
||||||
}
|
|
||||||
for (var k = 0; k < name.length; ++k) {
|
|
||||||
cls.prototype[name[k]] = func;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function $rt_asyncResult(value) {
|
function $rt_asyncResult(value) {
|
||||||
return function() {
|
return function() {
|
||||||
return value;
|
return value;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.teavm.javascript.spi.GeneratedBy;
|
||||||
import org.teavm.javascript.spi.InjectedBy;
|
import org.teavm.javascript.spi.InjectedBy;
|
||||||
import org.teavm.jso.JS;
|
import org.teavm.jso.JS;
|
||||||
import org.teavm.platform.metadata.ClassResource;
|
import org.teavm.platform.metadata.ClassResource;
|
||||||
|
import org.teavm.platform.metadata.StaticFieldResource;
|
||||||
import org.teavm.platform.plugin.PlatformGenerator;
|
import org.teavm.platform.plugin.PlatformGenerator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,6 +91,10 @@ public final class Platform {
|
||||||
|
|
||||||
@InjectedBy(PlatformGenerator.class)
|
@InjectedBy(PlatformGenerator.class)
|
||||||
@PluggableDependency(PlatformGenerator.class)
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
|
public static native Object objectFromResource(StaticFieldResource resource);
|
||||||
|
|
||||||
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
public static native Enum<?>[] getEnumConstants(PlatformClass cls);
|
public static native Enum<?>[] getEnumConstants(PlatformClass cls);
|
||||||
|
|
||||||
@GeneratedBy(PlatformGenerator.class)
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.platform.metadata;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
import org.teavm.model.ListableClassReaderSource;
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
import org.teavm.platform.Platform;
|
import org.teavm.platform.Platform;
|
||||||
import org.teavm.vm.TeaVM;
|
import org.teavm.vm.TeaVM;
|
||||||
|
@ -55,6 +56,12 @@ public interface MetadataGeneratorContext extends ServiceRepository {
|
||||||
*/
|
*/
|
||||||
ClassResource createClassResource(String className);
|
ClassResource createClassResource(String className);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new resource that represents static field. Client code then may use
|
||||||
|
* {@link Platform#objectFromResource(StaticFieldResource)} to get actual field value.
|
||||||
|
*/
|
||||||
|
StaticFieldResource createFieldResource(FieldReference field);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new resource array.
|
* Creates a new resource array.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform.metadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public interface StaticFieldResource extends Resource {
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform.plugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.teavm.codegen.SourceWriter;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
|
import org.teavm.platform.metadata.StaticFieldResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
class BuildTimeStaticFieldResource implements StaticFieldResource, ResourceWriter {
|
||||||
|
private FieldReference field;
|
||||||
|
|
||||||
|
public BuildTimeStaticFieldResource(FieldReference field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldReference getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(SourceWriter writer) throws IOException {
|
||||||
|
writer.appendField(field);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ package org.teavm.platform.plugin;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
import org.teavm.model.ListableClassReaderSource;
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
import org.teavm.platform.metadata.*;
|
import org.teavm.platform.metadata.*;
|
||||||
|
|
||||||
|
@ -72,6 +73,11 @@ class DefaultMetadataGeneratorContext implements MetadataGeneratorContext {
|
||||||
return new BuildTimeClassResource(className);
|
return new BuildTimeClassResource(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StaticFieldResource createFieldResource(FieldReference field) {
|
||||||
|
return new BuildTimeStaticFieldResource(field);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Resource> ResourceMap<T> createResourceMap() {
|
public <T extends Resource> ResourceMap<T> createResourceMap() {
|
||||||
return new BuildTimeResourceMap<>();
|
return new BuildTimeResourceMap<>();
|
||||||
|
|
|
@ -16,11 +16,7 @@
|
||||||
package org.teavm.platform.plugin;
|
package org.teavm.platform.plugin;
|
||||||
|
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.*;
|
||||||
import org.teavm.model.CallLocation;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.ClassReader;
|
|
||||||
import org.teavm.model.MethodDescriptor;
|
|
||||||
import org.teavm.model.MethodReader;
|
|
||||||
import org.teavm.model.ValueType;
|
|
||||||
import org.teavm.platform.Platform;
|
import org.teavm.platform.Platform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +25,6 @@ import org.teavm.platform.Platform;
|
||||||
*/
|
*/
|
||||||
public class EnumDependencySupport implements DependencyListener {
|
public class EnumDependencySupport implements DependencyListener {
|
||||||
private DependencyNode allEnums;
|
private DependencyNode allEnums;
|
||||||
private boolean unlocked;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void started(DependencyAgent agent) {
|
public void started(DependencyAgent agent) {
|
||||||
|
@ -43,21 +38,25 @@ public class EnumDependencySupport implements DependencyListener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
allEnums.propagate(agent.getType(className));
|
allEnums.propagate(agent.getType(className));
|
||||||
if (unlocked) {
|
|
||||||
MethodReader method = cls.getMethod(new MethodDescriptor("values",
|
|
||||||
ValueType.arrayOf(ValueType.object(cls.getName()))));
|
|
||||||
if (method != null) {
|
|
||||||
agent.linkMethod(method.getReference(), location).use();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
public void methodAchieved(final DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
if (method.getReference().getClassName().equals(Platform.class.getName()) &&
|
if (method.getReference().getClassName().equals(Platform.class.getName()) &&
|
||||||
method.getReference().getName().equals("getEnumConstants")) {
|
method.getReference().getName().equals("getEnumConstants")) {
|
||||||
unlocked = true;
|
|
||||||
allEnums.connect(method.getResult().getArrayItem());
|
allEnums.connect(method.getResult().getArrayItem());
|
||||||
|
final MethodReference ref = method.getReference();
|
||||||
|
allEnums.addConsumer(new DependencyConsumer() {
|
||||||
|
@Override public void consume(DependencyAgentType type) {
|
||||||
|
ClassReader cls = agent.getClassSource().get(type.getName());
|
||||||
|
MethodReader method = cls.getMethod(new MethodDescriptor("values",
|
||||||
|
ValueType.arrayOf(ValueType.object(cls.getName()))));
|
||||||
|
if (method != null) {
|
||||||
|
agent.linkMethod(method.getReference(), new CallLocation(ref)).use();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
method.getResult().propagate(agent.getType("[java.lang.Enum"));
|
method.getResult().propagate(agent.getType("[java.lang.Enum"));
|
||||||
for (String cls : agent.getAchievableClasses()) {
|
for (String cls : agent.getAchievableClasses()) {
|
||||||
classAchieved(agent, cls, location);
|
classAchieved(agent, cls, location);
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform.plugin;
|
||||||
|
|
||||||
|
import org.teavm.dependency.*;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
|
import org.teavm.platform.Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class PlatformDependencyListener implements DependencyListener {
|
||||||
|
private DependencyNode allClasses;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void started(DependencyAgent agent) {
|
||||||
|
allClasses = agent.createNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void classAchieved(DependencyAgent agent, String className, CallLocation location) {
|
||||||
|
allClasses.propagate(agent.getType(className));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void methodAchieved(final DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
|
if (!method.getReference().getClassName().equals(Platform.class.getName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (method.getReference().getName()) {
|
||||||
|
case "objectFromResource":
|
||||||
|
allClasses.connect(method.getResult());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fieldAchieved(DependencyAgent agent, FieldDependency field, CallLocation location) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ import org.teavm.javascript.spi.Injector;
|
||||||
import org.teavm.javascript.spi.InjectorContext;
|
import org.teavm.javascript.spi.InjectorContext;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.platform.Platform;
|
import org.teavm.platform.Platform;
|
||||||
|
import org.teavm.platform.PlatformClass;
|
||||||
import org.teavm.platform.PlatformRunnable;
|
import org.teavm.platform.PlatformRunnable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,12 +59,9 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
|
||||||
switch (methodRef.getName()) {
|
switch (methodRef.getName()) {
|
||||||
case "asJavaClass":
|
case "asJavaClass":
|
||||||
case "classFromResource":
|
case "classFromResource":
|
||||||
|
case "objectFromResource":
|
||||||
context.writeExpr(context.getArgument(0));
|
context.writeExpr(context.getArgument(0));
|
||||||
return;
|
return;
|
||||||
case "getEnumConstants":
|
|
||||||
context.writeExpr(context.getArgument(0));
|
|
||||||
context.getWriter().append(".values()");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +83,9 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
|
||||||
case "schedule":
|
case "schedule":
|
||||||
generateSchedule(context, writer, true);
|
generateSchedule(context, writer, true);
|
||||||
break;
|
break;
|
||||||
|
case "getEnumConstants":
|
||||||
|
generateEnumConstants(context, writer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,4 +204,30 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
|
||||||
writer.outdent().append("},").ws().append(timeout ? context.getParameterName(2) : "0")
|
writer.outdent().append("},").ws().append(timeout ? context.getParameterName(2) : "0")
|
||||||
.append(");").softNewLine();
|
.append(");").softNewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateEnumConstants(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||||
|
writer.append("var c").ws().append("=").ws().append("'$$enumConstants$$';").softNewLine();
|
||||||
|
for (String clsName : context.getClassSource().getClassNames()) {
|
||||||
|
ClassReader cls = context.getClassSource().get(clsName);
|
||||||
|
MethodReader method = cls.getMethod(new MethodDescriptor("values",
|
||||||
|
ValueType.arrayOf(ValueType.object(clsName))));
|
||||||
|
if (method != null) {
|
||||||
|
writer.appendClass(clsName).append("[c]").ws().append("=").ws();
|
||||||
|
writer.appendMethodBody(method.getReference());
|
||||||
|
writer.append(";").softNewLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String selfName = writer.getNaming().getFullNameFor(new MethodReference(Platform.class, "getEnumConstants",
|
||||||
|
PlatformClass.class, Enum[].class));
|
||||||
|
writer.append(selfName).ws().append("=").ws().append("function(cls)").ws().append("{").softNewLine().indent();
|
||||||
|
writer.append("if").ws().append("(!cls.hasOwnProperty(c))").ws().append("{").indent().softNewLine();
|
||||||
|
writer.append("return null;").softNewLine();
|
||||||
|
writer.outdent().append("}").softNewLine();
|
||||||
|
writer.append("return cls[c]();").softNewLine();
|
||||||
|
writer.outdent().append("}").softNewLine();
|
||||||
|
|
||||||
|
writer.append("return ").append(selfName).append("(").append(context.getParameterName(1))
|
||||||
|
.append(");").softNewLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,5 +33,6 @@ public class PlatformPlugin implements TeaVMPlugin {
|
||||||
host.add(new NewInstanceDependencySupport());
|
host.add(new NewInstanceDependencySupport());
|
||||||
host.add(new ClassLookupDependencySupport());
|
host.add(new ClassLookupDependencySupport());
|
||||||
host.add(new EnumDependencySupport());
|
host.add(new EnumDependencySupport());
|
||||||
|
host.add(new PlatformDependencyListener());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,9 @@ class ResourceAccessorDependencyListener implements DependencyListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
|
if (!method.getReference().getClassName().equals(ResourceAccessor.class.getName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (method.getReference().getName()) {
|
switch (method.getReference().getName()) {
|
||||||
case "castToString":
|
case "castToString":
|
||||||
method.getResult().propagate(agent.getType("java.lang.String"));
|
method.getResult().propagate(agent.getType("java.lang.String"));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user