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();
|
||||
int flags = 0;
|
||||
if (cls.getModifiers().contains(NodeModifier.ENUM)) {
|
||||
flags &= 1;
|
||||
flags |= 1;
|
||||
}
|
||||
writer.append(flags).append(',').ws();
|
||||
MethodHolder clinit = classSource.get(cls.getName()).getMethod(
|
||||
|
|
|
@ -328,23 +328,6 @@ function $rt_assertNotNaN(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 = "";
|
||||
function $rt_putStdout(ch) {
|
||||
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) {
|
||||
return function() {
|
||||
return value;
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.teavm.javascript.spi.GeneratedBy;
|
|||
import org.teavm.javascript.spi.InjectedBy;
|
||||
import org.teavm.jso.JS;
|
||||
import org.teavm.platform.metadata.ClassResource;
|
||||
import org.teavm.platform.metadata.StaticFieldResource;
|
||||
import org.teavm.platform.plugin.PlatformGenerator;
|
||||
|
||||
/**
|
||||
|
@ -90,6 +91,10 @@ public final class Platform {
|
|||
|
||||
@InjectedBy(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);
|
||||
|
||||
@GeneratedBy(PlatformGenerator.class)
|
||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.platform.metadata;
|
|||
|
||||
import java.util.Properties;
|
||||
import org.teavm.common.ServiceRepository;
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.ListableClassReaderSource;
|
||||
import org.teavm.platform.Platform;
|
||||
import org.teavm.vm.TeaVM;
|
||||
|
@ -55,6 +56,12 @@ public interface MetadataGeneratorContext extends ServiceRepository {
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
|
|
@ -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.util.Properties;
|
||||
import org.teavm.common.ServiceRepository;
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.ListableClassReaderSource;
|
||||
import org.teavm.platform.metadata.*;
|
||||
|
||||
|
@ -72,6 +73,11 @@ class DefaultMetadataGeneratorContext implements MetadataGeneratorContext {
|
|||
return new BuildTimeClassResource(className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StaticFieldResource createFieldResource(FieldReference field) {
|
||||
return new BuildTimeStaticFieldResource(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Resource> ResourceMap<T> createResourceMap() {
|
||||
return new BuildTimeResourceMap<>();
|
||||
|
|
|
@ -16,11 +16,7 @@
|
|||
package org.teavm.platform.plugin;
|
||||
|
||||
import org.teavm.dependency.*;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.platform.Platform;
|
||||
|
||||
/**
|
||||
|
@ -29,7 +25,6 @@ import org.teavm.platform.Platform;
|
|||
*/
|
||||
public class EnumDependencySupport implements DependencyListener {
|
||||
private DependencyNode allEnums;
|
||||
private boolean unlocked;
|
||||
|
||||
@Override
|
||||
public void started(DependencyAgent agent) {
|
||||
|
@ -43,21 +38,25 @@ public class EnumDependencySupport implements DependencyListener {
|
|||
return;
|
||||
}
|
||||
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
|
||||
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()) &&
|
||||
method.getReference().getName().equals("getEnumConstants")) {
|
||||
unlocked = true;
|
||||
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"));
|
||||
for (String cls : agent.getAchievableClasses()) {
|
||||
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.model.*;
|
||||
import org.teavm.platform.Platform;
|
||||
import org.teavm.platform.PlatformClass;
|
||||
import org.teavm.platform.PlatformRunnable;
|
||||
|
||||
/**
|
||||
|
@ -58,12 +59,9 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
|
|||
switch (methodRef.getName()) {
|
||||
case "asJavaClass":
|
||||
case "classFromResource":
|
||||
case "objectFromResource":
|
||||
context.writeExpr(context.getArgument(0));
|
||||
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":
|
||||
generateSchedule(context, writer, true);
|
||||
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")
|
||||
.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 ClassLookupDependencySupport());
|
||||
host.add(new EnumDependencySupport());
|
||||
host.add(new PlatformDependencyListener());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ class ResourceAccessorDependencyListener implements DependencyListener {
|
|||
|
||||
@Override
|
||||
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||
if (!method.getReference().getClassName().equals(ResourceAccessor.class.getName())) {
|
||||
return;
|
||||
}
|
||||
switch (method.getReference().getName()) {
|
||||
case "castToString":
|
||||
method.getResult().propagate(agent.getType("java.lang.String"));
|
||||
|
|
Loading…
Reference in New Issue
Block a user